diff --git a/.ipynb_checkpoints/plotly-checkpoint.ipynb b/.ipynb_checkpoints/plotly-checkpoint.ipynb index c53f888..b6b3519 100644 --- a/.ipynb_checkpoints/plotly-checkpoint.ipynb +++ b/.ipynb_checkpoints/plotly-checkpoint.ipynb @@ -9,12 +9,13 @@ }, { "cell_type": "code", - "execution_count": 29, + "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" @@ -24,21 +25,25 @@ "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." + "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": 61, + "execution_count": 6, "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "your credentials are:\n", - " {:api_key 6FaFG4sgtpLnDrvzvFT1, :username didier, :stream_ids [8rcf9eam9j zupv6k3u4k]}\n" - ] + "data": { + "text/plain": [ + "#'user/plotly-cred" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -52,7 +57,7 @@ " {})))\n", "\n", "(def plotly-cred (get-plotly-credentials))\n", - "(println \"your credentials are:\\n\" plotly-cred)" + ";; (println \"credentials are now loaded\" plotly-cred)" ] }, { @@ -66,44 +71,64 @@ }, { "cell_type": "code", - "execution_count": 86, + "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "#'user/upload-grid" + "#'user/plot-response" ] }, - "execution_count": 86, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "(defn upload-grid [grid cred] \n", - " (let [url \"https://api.plot.ly/v2/grids\";;\"https://api.plot.ly/v2/grids\" \"https://api.plot.ly/v2/grids\" ;;\n", - " headers {:Plotly-Client-Platform' \"curl\"}\n", - " auth \"didier:6FaFG4sgtpLnDrvzvFT1\"];;[(:username cred) (:api_key cred)]]\n", - " (println auth)\n", + "(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 grid :content-type :json})))" + " :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": 87, - "metadata": {}, + "execution_count": 4, + "metadata": { + "scrolled": true + }, "outputs": [ { "data": { - "text/plain": [ - "#'user/my-grid" + "text/html": [ + "" ] }, - "execution_count": 87, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -112,74 +137,55 @@ "(def my-grid {:data \n", " {:cols\n", " {\n", - " :height {:data [10 203 102 404] :order 1}\n", - " :weight {:data [112 234 321 34] :order 2}}}})\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": 87, + "execution_count": 5, "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "didier:6FaFG4sgtpLnDrvzvFT1\n", - "ExceptionInfo clj-http: status 401 {:request-time 908, :repeatable? false, :protocol-version {:name \"HTTP\", :major 1, :minor 1}, :streaming? true, :chunked? true, :reason-phrase \"UNAUTHORIZED\", :headers {\"Server\" \"nginx\", \"Via\" \"1.1 google\", \"Content-Type\" \"application/json\", \"Alt-Svc\" \"clear\", \"X-Frame-Options\" \"SAMEORIGIN\", \"Strict-Transport-Security\" \"max-age=31536000; includesubdomains; preload\", \"WWW-Authenticate\" \"Bearer realm=\\\"api\\\"\", \"Allow\" \"GET, POST, HEAD, OPTIONS\", \"Connection\" \"close\", \"Transfer-Encoding\" \"chunked\", \"Set-Cookie\" [\"plotly_sess_pr=z3l151u0weiecpy1jgmvp4bqaic9ksoo; Domain=.plot.ly; expires=Thu, 30-Nov-2017 03:09:02 GMT; httponly; Max-Age=1209600; Path=/; secure\" \"plotly_csrf_pr=b3rFF0ApmkYeHCK9Rjn9kKW30z2OyDkZ; Domain=.plot.ly; expires=Sat, 17-Nov-2018 03:09:02 GMT; Max-Age=31622400; Path=/; secure\" \"plotly_anoncsrf_pr=1Pv2vgnQIhIqOnw6bFy1kf4V2qAyXJ0r; Domain=.plot.ly; expires=Fri, 17-Nov-2017 03:09:02 GMT; httponly; Max-Age=86400; Path=/; secure\" \"GCLB=CNmkk46g4orXggE; path=/; HttpOnly; expires=Fri, 17-Nov-2017 03:09:02 GMT\"], \"Date\" \"Thu, 16 Nov 2017 03:09:02 GMT\", \"Vary\" \"Accept, Authorization, Cookie, Accept-Language\", \"x-xss-protection\" \"1; mode=block\", \"Content-Language\" \"en\"}, :orig-content-encoding nil, :status 401, :length -1, :body \"{\\\"errors\\\":[{\\\"code\\\":\\\"UNKNOWN\\\",\\\"message\\\":\\\"No Plotly-Client-Platform header found\\\",\\\"path\\\":null,\\\"field\\\":null}],\\\"detail\\\":\\\"No Plotly-Client-Platform header found\\\"}\", :trace-redirects []} slingshot.support/stack-trace (support.clj:201)\n" - ] - }, - { - "ename": "class clojure.lang.ExceptionInfo", - "evalue": "", - "output_type": "error", - "traceback": [ - " support.clj: 201 slingshot.support$stack_trace/invoke ", - " client.clj: 238 clj_http.client$exceptions_response/invokeStatic ", - " client.clj: 230 clj_http.client$exceptions_response/invoke ", - " client.clj: 248 clj_http.client$wrap_exceptions$fn__2420/invoke ", - " client.clj: 724 clj_http.client$wrap_accept$fn__2666/invoke ", - " client.clj: 746 clj_http.client$wrap_accept_encoding$fn__2673/invoke ", - " client.clj: 707 clj_http.client$wrap_content_type$fn__2660/invoke ", - " client.clj: 948 clj_http.client$wrap_form_params$fn__2769/invoke ", - " client.clj: 983 clj_http.client$wrap_nested_params$fn__2791/invoke ", - " client.clj: 882 clj_http.client$wrap_method$fn__2727/invoke ", - " cookies.clj: 131 clj_http.cookies$wrap_cookies$fn__773/invoke ", - " links.clj: 63 clj_http.links$wrap_links$fn__2196/invoke ", - " client.clj: 1009 clj_http.client$wrap_unknown_host$fn__2799/invoke ", - " client.clj: 1181 clj_http.client$request_STAR_/invokeStatic ", - " client.clj: 1174 clj_http.client$request_STAR_/invoke ", - " client.clj: 1199 clj_http.client$post/invokeStatic ", - " client.clj: 1195 clj_http.client$post/doInvoke ", - " RestFn.java: 423 clojure.lang.RestFn/invoke ", - " core.clj: 3206 clojure.core$eval/invokeStatic ", - " core.clj: 3202 clojure.core$eval/invoke ", - " main.clj: 243 clojure.main$repl$read_eval_print__8572$fn__8575/invoke", - " main.clj: 261 clojure.main$repl$fn__8581/invoke ", - " main.clj: 177 clojure.main$repl/doInvoke ", - " RestFn.java: 1523 clojure.lang.RestFn/invoke ", - " AFn.java: 152 clojure.lang.AFn/applyToHelper ", - " AFn.java: 144 clojure.lang.AFn/applyTo ", - " core.clj: 657 clojure.core$apply/invokeStatic ", - " core.clj: 1965 clojure.core$with_bindings_STAR_/invokeStatic ", - " RestFn.java: 425 clojure.lang.RestFn/invoke ", - " AFn.java: 22 clojure.lang.AFn/run ", - "ThreadPoolExecutor.java: 1149 java.util.concurrent.ThreadPoolExecutor/runWorker ", - "ThreadPoolExecutor.java: 624 java.util.concurrent.ThreadPoolExecutor$Worker/run ", - " Thread.java: 748 java.lang.Thread/run " - ] + "data": { + "text/html": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "(println (:body (upload-grid my-grid plotly-cred)))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "curl --user didier:6FaFG4sgtpLnDrvzvFT1 -H \"Content-Type: application/json\" -H \"Plotly-Client-Platform: curl\" https://api.plot.ly/v2/grids --data '{\"data\": { \"cols\": { \"first column\": {\"data\": [\"a\", \"b\", \"c\"], \"order\": 0}, \"second column\": {\"data\": [1, 2, 3], \"order\": 1} } } }'" + "(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" ] } ], diff --git a/highchart.ipynb b/highchart.ipynb index dc79d15..bf37c1c 100644 --- a/highchart.ipynb +++ b/highchart.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 43, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -14,7 +14,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -23,7 +23,7 @@ "" ] }, - "execution_count": 44, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -34,7 +34,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -43,7 +43,7 @@ "#'user/plot-highchart" ] }, - "execution_count": 45, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -52,23 +52,23 @@ "(defn plot-highchart [highchart-json]\n", " (let [id (str (java.util.UUID/randomUUID))\n", " code (format \"Highcharts.chart('%s', %s );\" id, (cheshire/encode highchart-json))\n", - " html [:div [:div {:id id}]\n", + " html [:div [:div {:id id :style {:background-color \"red\"}}]\n", " [:script code]]]\n", " (-> html hiccup/html display/make-html)))" ] }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
" + "
" ] }, - "execution_count": 63, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -83,6 +83,70 @@ " :series [{:data data-1} {:data data-2}]})" ] }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "should print some text\n" + ] + }, + { + "data": { + "text/html": [ + "

hello world

" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(println \"should print some text\")\n", + "(let [html [:h1 \"hello world\"]]\n", + " (-> html hiccup/html display/make-html))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "should show a svg\n" + ] + }, + { + "data": { + "text/html": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(println \"should show a svg\")\n", + "\n", + ";; \n", + ";; \n", + ";; \n", + "\n", + "(let [html [:svg {:height 100 :width 100}\n", + " [:circle {:cx 50 :cy 40 :r 40 :fill \"yellow\"}]]]\n", + " (-> html hiccup/html display/make-html))" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/project.clj b/project.clj index 0ca2314..1c617bc 100644 --- a/project.clj +++ b/project.clj @@ -4,7 +4,8 @@ :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[org.clojure/clojure "1.9.0-RC1"] - [clj-http "3.7.0"]] + [clj-http "3.7.0"] + [hiccup "1.0.5"]] :main ^:skip-aot graphly.core :plugins [[lein-jupyter "0.1.10"]] :target-path "target/%s"