{
"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": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"#'user/plotly-cred"
]
},
"execution_count": 2,
"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))))"
]
},
{
"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"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"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
}