4 Comparing the data representations of ggplot plots
| This is part of the Scicloj Clojure Data Tutorials. |
(ns comparing
(:require [clojisr.v1.r :as r :refer [r r$ r->clj]]
[clojisr.v1.applications.plotting :as plotting]
[scicloj.kindly.v4.kind :as kind]
[clojure.walk :as walk]
[tablecloth.api :as tc]
[editscript.core :as editscript]
[clojure.pprint :as pp]
[clojure.string :as str]
[representing]))4.1 Exlploring a few plots
Let us explore and compare a few plots through their Clojure representations:
(defn h3 [title] (kind/hiccup [:h3 title]))(defn h4 [title] (kind/hiccup [:h4 title]))(defn ggplot-summary
([title r-code]
(ggplot-summary r-code))
([title r-code prev-clj-to-compare]
(let [plot (r r-code)
clj (-> plot
representing/ggplot->clj
(dissoc :data))]
{:title title
:r-code r-code
:image (plotting/plot->buffered-image plot)
:clj clj
:diff (when prev-clj-to-compare
(-> prev-clj-to-compare
(editscript/diff clj)
pp/pprint
with-out-str
(str/replace #": " ":_ ")
read-string))})))(defn view-summary [{:keys [title r-code image clj diff]}]
(kind/fragment
[(h3 title)
(h4 "R code")
(kind/md
(format "\n```\n%s\n```\n"
r-code))
(h4 "plot")
image
(h4 "clj data")
clj
(when diff
(kind/fragment
[(h4 "clj diff with previous")
diff]))]))(->> [;;
["A scatterplot"
"(ggplot(mpg, aes(cty, hwy))
+ geom_point())"]
;;
["A scatterplot with colours"
"(ggplot(mpg, aes(cty, hwy, color=factor(cyl)))
+ geom_point())"]
;;
["A scatterplot with colours and smoothing"
"(ggplot(mpg, aes(cty, hwy, color=factor(cyl)))
+ geom_point()
+ stat_smooth(method=\"lm\"))"]
;;
["A scatterplot with colours, smoothing, and facets"
"(ggplot(mpg, aes(cty, hwy, color=factor(cyl)))
+ geom_point()
+ stat_smooth(method=\"lm\")
+ facet_wrap(~cyl))"]]
(reductions (fn [prev-summary [title r-code]]
(ggplot-summary title
r-code
(:clj prev-summary)))
nil)
rest
(map view-summary)
kind/fragment)A scatterplot
R code
(ggplot(mpg, aes(cty, hwy))
+ geom_point())
plot
clj data
{:labels {:x ["cty"], :y ["hwy"]},
:coordinates
{:expand [true],
:clip ["on"],
:limits {:x nil, :y nil},
:super :ggproto-method,
:default [true]},
:layout {:super :ggproto-method},
:mapping {:x [~ cty], :y [~ hwy]},
:facet {:shrink [true], :super :ggproto-method},
:scales {:scales [], :super :ggproto-method},
:theme [],
:guides {:guides nil, :super :ggproto-method},
:layers
[{:aes_params [],
:stat {:compute_layer :ggproto-method, :super :ggproto-method},
:show.legend [nil],
:mapping nil,
:super :ggproto-method,
:inherit.aes [true],
:geom_params {:na.rm [false]},
:geom
{:non_missing_aes ["size" "shape" "colour"],
:draw_key :ggproto-method,
:default_aes
{:shape [19.0],
:colour ["black"],
:size [1.5],
:fill [nil],
:alpha [nil],
:stroke [0.5]},
:super :ggproto-method,
:required_aes ["x" "y"],
:draw_panel :ggproto-method},
:stat_params {:na.rm [false]},
:constructor [geom_point],
:position {:compute_layer :ggproto-method, :super :ggproto-method},
:data []}]}nilA scatterplot with colours
R code
(ggplot(mpg, aes(cty, hwy, color=factor(cyl)))
+ geom_point())
plot
clj data
{:labels {:x ["cty"], :y ["hwy"], :colour ["factor(cyl)"]},
:coordinates
{:expand [true],
:clip ["on"],
:limits {:x nil, :y nil},
:super :ggproto-method,
:default [true]},
:layout {:super :ggproto-method},
:mapping {:x [~ cty], :y [~ hwy], :colour [~ [factor cyl]]},
:facet {:shrink [true], :super :ggproto-method},
:scales {:scales [], :super :ggproto-method},
:theme [],
:guides {:guides nil, :super :ggproto-method},
:layers
[{:aes_params [],
:stat {:compute_layer :ggproto-method, :super :ggproto-method},
:show.legend [nil],
:mapping nil,
:super :ggproto-method,
:inherit.aes [true],
:geom_params {:na.rm [false]},
:geom
{:non_missing_aes ["size" "shape" "colour"],
:draw_key :ggproto-method,
:default_aes
{:shape [19.0],
:colour ["black"],
:size [1.5],
:fill [nil],
:alpha [nil],
:stroke [0.5]},
:super :ggproto-method,
:required_aes ["x" "y"],
:draw_panel :ggproto-method},
:stat_params {:na.rm [false]},
:constructor [geom_point],
:position {:compute_layer :ggproto-method, :super :ggproto-method},
:data []}]}clj diff with previous
[[[:labels :colour] :+ ["factor(cyl)"]]
[[:mapping :colour] :+ [~[factor cyl]]]]A scatterplot with colours and smoothing
R code
(ggplot(mpg, aes(cty, hwy, color=factor(cyl)))
+ geom_point()
+ stat_smooth(method="lm"))
plot
clj data
{:labels {:x ["cty"], :y ["hwy"], :colour ["factor(cyl)"]},
:coordinates
{:expand [true],
:clip ["on"],
:limits {:x nil, :y nil},
:super :ggproto-method,
:default [true]},
:layout {:super :ggproto-method},
:mapping {:x [~ cty], :y [~ hwy], :colour [~ [factor cyl]]},
:facet {:shrink [true], :super :ggproto-method},
:scales {:scales [], :super :ggproto-method},
:theme [],
:guides {:guides nil, :super :ggproto-method},
:layers
[{:aes_params [],
:stat {:compute_layer :ggproto-method, :super :ggproto-method},
:show.legend [nil],
:mapping nil,
:super :ggproto-method,
:inherit.aes [true],
:geom_params {:na.rm [false]},
:geom
{:non_missing_aes ["size" "shape" "colour"],
:draw_key :ggproto-method,
:default_aes
{:shape [19.0],
:colour ["black"],
:size [1.5],
:fill [nil],
:alpha [nil],
:stroke [0.5]},
:super :ggproto-method,
:required_aes ["x" "y"],
:draw_panel :ggproto-method},
:stat_params {:na.rm [false]},
:constructor [geom_point],
:position {:compute_layer :ggproto-method, :super :ggproto-method},
:data []}
{:aes_params [],
:stat
{:extra_params ["na.rm" "orientation"],
:super :ggproto-method,
:compute_group :ggproto-method,
:required_aes ["x" "y"],
:setup_params :ggproto-method,
:dropped_aes ["weight"]},
:show.legend [nil],
:mapping nil,
:super :ggproto-method,
:inherit.aes [true],
:geom_params {:se [true], :na.rm [false], :orientation [nil]},
:geom
{:setup_params :ggproto-method,
:super :ggproto-method,
:draw_key :ggproto-method,
:extra_params ["na.rm" "orientation"],
:required_aes ["x" "y"],
:draw_group :ggproto-method,
:optional_aes ["ymin" "ymax"],
:rename_size [true],
:setup_data :ggproto-method,
:default_aes
{:colour ["#3366FF"],
:fill ["grey60"],
:linewidth [1.0],
:linetype [1.0],
:weight [1.0],
:alpha [0.4]}},
:stat_params
{:na.rm [false],
:method ["lm"],
:n [80.0],
:xseq nil,
:orientation [nil],
:level [0.95],
:fullrange [false],
:se [true],
:formula nil,
:method.args [],
:span [0.75]},
:constructor {: nil, :method ["lm"]},
:position {:compute_layer :ggproto-method, :super :ggproto-method},
:data []}]}clj diff with previous
[[[:layers 1]
:+
{:aes_params [],
:stat
{:extra_params ["na.rm" "orientation"],
:super :ggproto-method,
:compute_group :ggproto-method,
:required_aes ["x" "y"],
:setup_params :ggproto-method,
:dropped_aes ["weight"]},
:show.legend [nil],
:mapping nil,
:super :ggproto-method,
:inherit.aes [true],
:geom_params {:se [true], :na.rm [false], :orientation [nil]},
:geom
{:setup_params :ggproto-method,
:super :ggproto-method,
:draw_key :ggproto-method,
:extra_params ["na.rm" "orientation"],
:required_aes ["x" "y"],
:draw_group :ggproto-method,
:optional_aes ["ymin" "ymax"],
:rename_size [true],
:setup_data :ggproto-method,
:default_aes
{:colour ["#3366FF"],
:fill ["grey60"],
:linewidth [1.0],
:linetype [1.0],
:weight [1.0],
:alpha [0.4]}},
:stat_params
{:na.rm [false],
:method ["lm"],
:n [80.0],
:xseq nil,
:orientation [nil],
:level [0.95],
:fullrange [false],
:se [true],
:formula nil,
:method.args [],
:span [0.75]},
:constructor {:_ nil, :method ["lm"]},
:position {:compute_layer :ggproto-method, :super :ggproto-method},
:data []}]]A scatterplot with colours, smoothing, and facets
R code
(ggplot(mpg, aes(cty, hwy, color=factor(cyl)))
+ geom_point()
+ stat_smooth(method="lm")
+ facet_wrap(~cyl))
plot
clj data
{:labels {:x ["cty"], :y ["hwy"], :colour ["factor(cyl)"]},
:coordinates
{:expand [true],
:clip ["on"],
:limits {:x nil, :y nil},
:super :ggproto-method,
:default [true]},
:layout {:super :ggproto-method},
:mapping {:x [~ cty], :y [~ hwy], :colour [~ [factor cyl]]},
:facet
{:params
{:axis_labels {:x [true], :y [true]},
:dir ["h"],
:draw_axes {:x [false], :y [false]},
:nrow nil,
:as.table [true],
:free {:x [false], :y [false]},
:drop [true],
:strip.position ["top"],
:ncol nil,
:facets {:cyl [~ cyl]},
:labeller
"function (labels, multi_line = TRUE) \n{\n labels <- lapply(labels, as.character)\n if (multi_line) {\n labels\n }\n else {\n collapse_labels_lines(labels)\n }\n}\n<bytecode: 0x560984ec79a0>\n<environment: namespace:ggplot2>\nattr(,\"class\")\n[1] \"function\" \"labeller\"\n"},
:shrink [true],
:super :ggproto-method},
:scales {:scales [], :super :ggproto-method},
:theme [],
:guides {:guides nil, :super :ggproto-method},
:layers
[{:aes_params [],
:stat {:compute_layer :ggproto-method, :super :ggproto-method},
:show.legend [nil],
:mapping nil,
:super :ggproto-method,
:inherit.aes [true],
:geom_params {:na.rm [false]},
:geom
{:non_missing_aes ["size" "shape" "colour"],
:draw_key :ggproto-method,
:default_aes
{:shape [19.0],
:colour ["black"],
:size [1.5],
:fill [nil],
:alpha [nil],
:stroke [0.5]},
:super :ggproto-method,
:required_aes ["x" "y"],
:draw_panel :ggproto-method},
:stat_params {:na.rm [false]},
:constructor [geom_point],
:position {:compute_layer :ggproto-method, :super :ggproto-method},
:data []}
{:aes_params [],
:stat
{:extra_params ["na.rm" "orientation"],
:super :ggproto-method,
:compute_group :ggproto-method,
:required_aes ["x" "y"],
:setup_params :ggproto-method,
:dropped_aes ["weight"]},
:show.legend [nil],
:mapping nil,
:super :ggproto-method,
:inherit.aes [true],
:geom_params {:se [true], :na.rm [false], :orientation [nil]},
:geom
{:setup_params :ggproto-method,
:super :ggproto-method,
:draw_key :ggproto-method,
:extra_params ["na.rm" "orientation"],
:required_aes ["x" "y"],
:draw_group :ggproto-method,
:optional_aes ["ymin" "ymax"],
:rename_size [true],
:setup_data :ggproto-method,
:default_aes
{:colour ["#3366FF"],
:fill ["grey60"],
:linewidth [1.0],
:linetype [1.0],
:weight [1.0],
:alpha [0.4]}},
:stat_params
{:na.rm [false],
:method ["lm"],
:n [80.0],
:xseq nil,
:orientation [nil],
:level [0.95],
:fullrange [false],
:se [true],
:formula nil,
:method.args [],
:span [0.75]},
:constructor {: nil, :method ["lm"]},
:position {:compute_layer :ggproto-method, :super :ggproto-method},
:data []}]}clj diff with previous
[[[:facet :params]
:+
{:axis_labels {:x [true], :y [true]},
:dir ["h"],
:draw_axes {:x [false], :y [false]},
:nrow nil,
:as.table [true],
:free {:x [false], :y [false]},
:drop [true],
:strip.position ["top"],
:ncol nil,
:facets {:cyl [~cyl]},
:labeller
"function (labels, multi_line = TRUE) \n{\n labels <- lapply(labels, as.character)\n if (multi_line) {\n labels\n }\n else {\n collapse_labels_lines(labels)\n }\n}\n<bytecode:_ 0x560984ec79a0>\n<environment:_ namespace:ggplot2>\nattr(,\"class\")\n[1] \"function\" \"labeller\"\n"}]]