{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## plotly implementation" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "(require '[clojupyter.misc.display :as display]\n", " '[clojure.java.io :as io]\n", " '[hiccup.core :as hiccup]\n", " '[cheshire.core :as cheshire]\n", " '[clj-http.client :as client]\n", " '[clojure.repl :refer :all]) ;; to have all the repl goodies" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To access plotly api, we need an api key. The standard way is to store the api key in `$HOME/.plotly/.credentials` in a json object as defined in https://plot.ly/python/getting-started/. For that you will need to create a plotly account.\n", "\n", "(For whatever reason, I believe plotly's python api does not load the credentials automatically from this location.)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "#'user/plotly-cred" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(defn get-plotly-credentials\n", " \"Returs the plotly credentials in $HOME/.plotly/.credentials\"\n", " []\n", " (let [home (-> \"HOME\" System/getenv io/as-file)\n", " credential-file (io/file home \".plotly\" \".credentials\")]\n", " (if (.exists credential-file)\n", " (-> credential-file slurp (cheshire/parse-string true))\n", " {})))\n", "\n", "(def plotly-cred (get-plotly-credentials))\n", ";; (println \"credentials are now loaded\" plotly-cred)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "Next, we need to create \"grids\". Grids are dataset stored on plotly that we can then plot. The plotting is done in two phases, uploding the datasets and then plotting the datasets." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "#'user/plot-response" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(defn post-to-endpoint\n", " \"General method to POST to a plotly endpoint.\"\n", " [endpoint payload cred]\n", " (let [url endpoint\n", " headers {:Plotly-Client-Platform \"curl\"}\n", " auth [(:username cred) (:api_key cred)]]\n", " (client/post url {:basic-auth auth\n", " :headers headers\n", " :throw-entire-message? true\n", " :form-params payload \n", " :content-type :json})))\n", "\n", "(defn post-to-grid [grid cred] \n", " (post-to-endpoint \"https://api.plot.ly/v2/grids\" grid cred))\n", "\n", "(defn post-to-plot [grid cred] \n", " (post-to-endpoint \"https://api.plot.ly/v2/plots\" grid cred))\n", "\n", "(defn plot-response [plotly-data]\n", " (let [to-iframe (fn [url] [:iframe {:src url :width \"100%\" :height 200 :scrolling \"no\" :frameborder \"0\"}])]\n", " (-> plotly-data\n", " (:file)\n", " (:embed_url)\n", " to-iframe \n", " (hiccup/html)\n", " (display/make-html))))\n", " " ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/html": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def my-grid {:data \n", " {:cols\n", " {\n", " :height {:data [10 203 102 404] :order 0}\n", " :weight1 {:data [112 234 321 34] :order 1}\n", " :weight2 {:data [112 234 321 34] :order 2}\n", " :weight3 {:data [112 234 321 34] :order 3}\n", " :weight4 {:data [112 234 321 34] :order 4}}}})\n", "\n", "(def resp-data (-> my-grid\n", " (post-to-grid plotly-cred)\n", " (:body)\n", " (cheshire/decode true)))\n", "(def plotly-data (plot-response resp-data))\n", "plotly-data" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(defn post-to-plot [grid cred] \n", " (post-to-endpoint \"https://api.plot.ly/v2/plots\" grid cred))\n", "(def bar-char {:data [\n", " {\n", " :xsrc \"jackp:16731:7a9501\" ;; someone else data. but we could very well use the above grid using reference\n", " :ysrc \"jackp:16731:948d9c\" ;; someone else data. but we could very well use the above grid using reference\n", " :hoverinfo \"none\"\n", " :type \"bar\"\n", " :marker {:color \"rgb(227, 119, 194)\"}}]})\n", "\n", "(def payload (assoc {:world_readable true} :figure bar-char))\n", "\n", "(def plot-data (-> payload\n", " (post-to-plot plotly-cred)\n", " (:body)\n", " (cheshire/decode true)\n", " (plot-response)))\n", "plot-data" ] } ], "metadata": { "kernelspec": { "display_name": "Lein-Clojure", "language": "clojure", "name": "lein-clojure" }, "language_info": { "file_extension": ".clj", "mimetype": "text/x-clojure", "name": "clojure", "version": "1.9.0-RC1" } }, "nbformat": 4, "nbformat_minor": 2 }