Files
graphly/plotly.ipynb

6.4 KiB

plotly implementation

In [1]:
(require '[clojupyter.misc.display :as display]
         '[clojure.java.io :as io]
         '[hiccup.core :as hiccup]
         '[cheshire.core :as cheshire]
         '[clj-http.client :as client]
         '[clojure.repl :refer :all])  ;; to have all the repl goodies

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.

(For whatever reason, I believe plotly's python api does not load the credentials automatically from this location.)

In [2]:
(defn get-plotly-credentials
    "Returs the plotly credentials in $HOME/.plotly/.credentials"
    []
    (let [home (-> "HOME" System/getenv io/as-file)
          credential-file (io/file home ".plotly" ".credentials")]
        (if (.exists credential-file)
            (-> credential-file slurp (cheshire/parse-string true))
            {})))

(def plotly-cred  (get-plotly-credentials))
;; (println "credentials are now loaded" plotly-cred)
Out [2]:
#'user/plotly-cred

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.

In [3]:
(defn post-to-endpoint
  "General method to POST to a plotly endpoint."
  [endpoint payload cred]
  (let [url endpoint
        headers {:Plotly-Client-Platform "curl"}
        auth [(:username cred) (:api_key cred)]]
    (client/post url {:basic-auth auth
                      :headers headers
                      :throw-entire-message? true
                      :form-params payload 
                      :content-type :json})))

(defn post-to-grid [grid cred] 
    (post-to-endpoint "https://api.plot.ly/v2/grids" grid cred))

(defn post-to-plot [grid cred] 
    (post-to-endpoint "https://api.plot.ly/v2/plots" grid cred))

(defn plot-response [plotly-data]
    (let [to-iframe (fn [url] [:iframe {:src url :width "100%" :height 200 :scrolling "no" :frameborder "0"}])]
      (-> plotly-data
          (:file)
          (:embed_url)
          to-iframe 
          (hiccup/html)
          (display/make-html))))
Out [3]:
#'user/plot-response
In [4]:
(def my-grid {:data 
              {:cols
               {
                   :height {:data [10 203 102 404] :order 0}
                   :weight1 {:data [112 234 321 34] :order 1}
                   :weight2 {:data [112 234 321 34] :order 2}
                   :weight3 {:data [112 234 321 34] :order 3}
                   :weight4 {:data [112 234 321 34] :order 4}}}})

(def resp-data (-> my-grid
                   (post-to-grid plotly-cred)
                   (:body)
                   (cheshire/decode true)))
(def plotly-data (plot-response resp-data))
plotly-data
Out [4]:
In [5]:
(defn post-to-plot [grid cred] 
    (post-to-endpoint "https://api.plot.ly/v2/plots" grid cred))
(def bar-char {:data [
                         {
                          :xsrc "jackp:16731:7a9501"  ;; someone else data.  but we could very well use the above grid using reference
                          :ysrc "jackp:16731:948d9c"  ;; someone else data.  but we could very well use the above grid using reference
                          :hoverinfo "none"
                          :type "bar"
                          :marker {:color "rgb(227, 119, 194)"}}]})

(def payload (assoc {:world_readable true} :figure bar-char))

(def plot-data (-> payload
                   (post-to-plot  plotly-cred)
                   (:body)
                   (cheshire/decode true)
                   (plot-response)))
plot-data
Out [5]:
In [ ]: