-
-
Save otfrom/2785ab6767d2e887d6f44e357b968f9f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns witan.cic.tuairisc.alpha.clerk.charting | |
(:require | |
[nextjournal.clerk :as clerk] | |
[tablecloth.api :as tc])) | |
(defn color-and-shape-lookup [domain] | |
(tc/dataset | |
{:domain-value domain | |
:color (cycle ["#29733c" "#fa814c" "#256cc6" "#fbe44c" "#50b938" "#59c4b8"]) | |
:shape (cycle ["circle", "square", "cross", "diamond", "triangle-up", "triangle-down", "triangle-right", "triangle-left"])})) | |
(defn color-map [plot-data color-field color-lookup] | |
(let [group-keys (into (sorted-set) (get plot-data color-field)) | |
filtered-colors (tc/select-rows color-lookup #(group-keys (get % :domain-value)))] | |
{:field color-field | |
:scale {:range (into [] (:color filtered-colors)) | |
:domain (into [] (:domain-value filtered-colors))}})) | |
(defn shape-map [plot-data shape-field shape-lookup] | |
(let [group-keys (into (sorted-set) (get plot-data shape-field)) | |
filtered-shapes (tc/select-rows shape-lookup #(group-keys (get % :domain-value)))] | |
{:field shape-field | |
:scale {:range (into [] (:shape filtered-shapes)) | |
:domain (into [] (:domain-value filtered-shapes))}})) | |
(defn line-plot | |
[{:keys [data | |
chart-title | |
chart-height chart-width | |
clerk-width | |
x x-title x-format | |
y y-title | |
group group-title | |
colors-and-shapes] | |
:or {chart-height 640 | |
chart-width 825 | |
clerk-width :full}}] | |
(clerk/vl | |
{::clerk/width clerk-width} | |
{:height chart-height | |
:width chart-width | |
:title {:text chart-title | |
:fontSize 24} | |
:config {:legend {:titleFontSize 20 | |
:labelFontSize 14} | |
:axisX {:titleFontSize 16 | |
:labelFontSize 12} | |
:axisY {:titleFontSize 16 | |
:labelFontSize 12}} | |
:data {:values (tc/rows data :as-maps)} | |
:layer [{:mark {:type "line", :point {:filled false, | |
:fill "white", | |
:size 50 | |
:strokeWidth 0.5}}, | |
:encoding {:y {:field y, :title y-title :type "quantitative"}, | |
:x {:field x, :title x-title :type "temporal"}, | |
;; color and shape scale and range must be specified or you get extra things in the legend | |
:color (color-map data group colors-and-shapes) | |
:shape (shape-map data group colors-and-shapes) | |
:tooltip [{:field group, :title group-title}, | |
{:field x, :type "temporal", :format x-format, :title x-title}, | |
{:field y, :title y-title}]}}]})) | |
(defn line-and-ribbon-plot | |
[{:keys [data | |
chart-title | |
chart-height chart-width | |
clerk-width | |
x x-title x-format | |
y y-title | |
irl iru ir-title | |
orl oru or-title | |
group group-title | |
colors-and-shapes] | |
:or {chart-height 640 | |
chart-width 825 | |
clerk-width :full}}] | |
(clerk/vl | |
{::clerk/width clerk-width} | |
{:height chart-height | |
:width chart-width | |
:title {:text chart-title | |
:fontSize 24} | |
:config {:legend {:titleFontSize 20 | |
:labelFontSize 14} | |
:axisX {:titleFontSize 16 | |
:labelFontSize 12} | |
:axisY {:titleFontSize 16 | |
:labelFontSize 12}} | |
:data {:values (-> data | |
(tc/map-columns :ir [irl iru] (fn [lower upper] | |
(format "%,f - %,1f" lower upper))) | |
(tc/map-columns :or [orl oru] (fn [lower upper] | |
(format "%,1f - %,1f" lower upper))) | |
(tc/rows :as-maps))} | |
:layer [{:mark "errorband" | |
:encoding {:y {:field iru :title y-title :type "quantitative"} | |
:y2 {:field irl} | |
:x {:field x :title x-title :type "temporal"} | |
:color {:field group :title group-title} | |
:tooltip [{:field group, :title group-title}, | |
{:field x, :type "temporal", :format x-format, :title x-title}, | |
{:field y, :title y-title} | |
{:field :ir :title ir-title} | |
{:field :or :title or-title}]}} | |
{:mark "errorband" | |
:encoding {:y {:field oru :title y-title :type "quantitative"} | |
:y2 {:field orl} | |
:x {:field x :title x-title :type "temporal"} | |
:color {:field group :title group-title} | |
:tooltip [{:field group, :title group-title}, | |
{:field x, :type "temporal", :format x-format, :title x-title}, | |
{:field y, :title y-title} | |
{:field :ir :title ir-title} | |
{:field :or :title or-title}]}} | |
{:mark {:type "line", :point {:filled false, | |
:fill "white", | |
:size 50 | |
:strokeWidth 0.5}}, | |
:encoding {:y {:field y, :title y-title :type "quantitative"}, | |
:x {:field x, :title x-title :type "temporal"}, | |
;; color and shape scale and range must be specified or you get extra things in the legend | |
:color (color-map data group colors-and-shapes) | |
:shape (shape-map data group colors-and-shapes) | |
:tooltip [{:field group, :title group-title}, | |
{:field x, :type "temporal", :format x-format, :title x-title}, | |
{:field y, :title y-title} | |
{:field :ir :title ir-title} | |
{:field :or :title or-title}]}}]})) | |
(comment | |
(def pa-lookup (color-and-shape-lookup (into (sorted-set "K2" "P2H5" "Q2") (:placement-type placement-analysis)))) | |
(line-plot {:data (-> costs-by-placement | |
;; (tc/map-columns "Week" :string [:week-starts] (fn [d] (str d))) | |
(ds/column-map "Week" str [:week-start]) | |
(tc/rename-columns {:placement-type "Placement" :week-starts "Week" :median "Median"})) | |
:chart-title "Weeks in care by placement type" | |
:x "Week" :x-title "Week" :x-format "%b %Y" | |
:y "Median" :y-title "# of Children Looked After" | |
:group "Placement" :group-title "Placement" | |
:colors-and-shapes lookup}) | |
;;; ## Weeks in Care by Placement Type | |
(line-and-ribbon-plot | |
{:data (-> costs-by-placement | |
(tc/map-columns :week-start [:week-start] (fn [d] (str d)))) | |
:chart-title "Weeks in care by placement type" | |
:x :week-start :x-title "Week" :x-format "%b %Y" | |
:y :median :y-title "# of Children Looked After" | |
:irl :q1 :iru :q3 :ir-title "50% range" | |
:orl :low-5 :oru :hi-95 :or-title "90% range" | |
:group :placement-type :group-title "Placement" | |
:colors-and-shapes pa-lookup}) | |
) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment