Skip to content

Commit 30bdf4f

Browse files
authored
Merge pull request #25 from tdhopper/add-seaborn-objects
Add seaborn.objects column to the plotting comparison
2 parents cc92ad4 + 61d6de7 commit 30bdf4f

4 files changed

Lines changed: 307 additions & 10 deletions

File tree

Examples.ipynb

Lines changed: 286 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,93 @@
55
"execution_count": null,
66
"metadata": {},
77
"outputs": [],
8-
"source": "%matplotlib inline\n\nimport readline\nimport altair as alt\nimport pandas as pd\nimport seaborn as sns\nfrom matplotlib import pyplot\nfrom plotnine import *\nimport numpy as np\n\nfrom plotly import figure_factory\nfrom plotly import graph_objects\nimport plotly.express as px\nfrom IPython.core.magic import Magics, magics_class, cell_magic\n\nfrom IPython.display import Image\n\nfrom pylab import rcParams\n\nsize = 20\nparams = {\n \"legend.fontsize\": size,\n \"figure.figsize\": (15, 5),\n \"axes.labelsize\": size,\n \"axes.titlesize\": size,\n \"xtick.labelsize\": size,\n \"ytick.labelsize\": size,\n \"axes.titlesize\": 1.5 * size,\n \"figure.figsize\": (12, 12),\n}\nrcParams.update(params)\ntheme_update(\n figure_size=(9, 9),\n title=element_text(size=size),\n text=element_text(size=0.6 * size),\n) # for plotnine\n\n\nimport plotly.io as pio\npio.renderers.default = \"png\"\npio.renderers[\"png\"].width = 750\npio.renderers[\"png\"].height = 750\n\n# Render Altair charts as PNG via vl-convert\nalt.renderers.enable(\"png\", scale_factor=2.0)\n\nimport tempfile\n\nimport lets_plot as lp\nfrom lets_plot.export import ggsave\n\nlp.LetsPlot.setup_html()\nlp.LetsPlot.set_theme(\n lp.theme(text=lp.element_text(size=16), title=lp.element_text(size=20))\n)\n\n_LETS_PLOT_DIR = tempfile.mkdtemp(prefix=\"lets-plot-\")\n\n\ndef _lets_plot_png(plot):\n \"\"\"Render a Lets-Plot spec to PNG so the cell output carries an image.\"\"\"\n path = ggsave(plot + lp.ggsize(750, 750), \"plot.png\", path=_LETS_PLOT_DIR)\n with open(path, \"rb\") as f:\n return f.read()\n\n\nget_ipython().display_formatter.formatters[\"image/png\"].for_type(\n lp.plot.core.PlotSpec, _lets_plot_png\n)"
8+
"source": [
9+
"%matplotlib inline\n",
10+
"\n",
11+
"import readline\n",
12+
"import altair as alt\n",
13+
"import pandas as pd\n",
14+
"import seaborn as sns\n",
15+
"from matplotlib import pyplot\n",
16+
"from plotnine import *\n",
17+
"import numpy as np\n",
18+
"\n",
19+
"from plotly import figure_factory\n",
20+
"from plotly import graph_objects\n",
21+
"import plotly.express as px\n",
22+
"from IPython.core.magic import Magics, magics_class, cell_magic\n",
23+
"\n",
24+
"from IPython.display import Image\n",
25+
"\n",
26+
"from pylab import rcParams\n",
27+
"\n",
28+
"size = 20\n",
29+
"params = {\n",
30+
" \"legend.fontsize\": size,\n",
31+
" \"figure.figsize\": (15, 5),\n",
32+
" \"axes.labelsize\": size,\n",
33+
" \"axes.titlesize\": size,\n",
34+
" \"xtick.labelsize\": size,\n",
35+
" \"ytick.labelsize\": size,\n",
36+
" \"axes.titlesize\": 1.5 * size,\n",
37+
" \"figure.figsize\": (12, 12),\n",
38+
"}\n",
39+
"rcParams.update(params)\n",
40+
"theme_update(\n",
41+
" figure_size=(9, 9),\n",
42+
" title=element_text(size=size),\n",
43+
" text=element_text(size=0.6 * size),\n",
44+
") # for plotnine\n",
45+
"\n",
46+
"\n",
47+
"import seaborn.objects as so\n",
48+
"\n",
49+
"# Match the other libraries: ~750x750 px output with scaled-up text\n",
50+
"so.Plot.config.display[\"scaling\"] = 1\n",
51+
"so.Plot.config.theme.update(\n",
52+
" {\n",
53+
" \"figure.figsize\": (8, 8),\n",
54+
" \"axes.labelsize\": size,\n",
55+
" \"axes.titlesize\": 1.5 * size,\n",
56+
" \"xtick.labelsize\": size,\n",
57+
" \"ytick.labelsize\": size,\n",
58+
" \"legend.fontsize\": size,\n",
59+
" \"legend.title_fontsize\": size,\n",
60+
" }\n",
61+
")\n",
62+
"\n",
63+
"import plotly.io as pio\n",
64+
"pio.renderers.default = \"png\"\n",
65+
"pio.renderers[\"png\"].width = 750\n",
66+
"pio.renderers[\"png\"].height = 750\n",
67+
"\n",
68+
"# Render Altair charts as PNG via vl-convert\n",
69+
"alt.renderers.enable(\"png\", scale_factor=2.0)\n",
70+
"\n",
71+
"import tempfile\n",
72+
"\n",
73+
"import lets_plot as lp\n",
74+
"from lets_plot.export import ggsave\n",
75+
"\n",
76+
"lp.LetsPlot.setup_html()\n",
77+
"lp.LetsPlot.set_theme(\n",
78+
" lp.theme(text=lp.element_text(size=16), title=lp.element_text(size=20))\n",
79+
")\n",
80+
"\n",
81+
"_LETS_PLOT_DIR = tempfile.mkdtemp(prefix=\"lets-plot-\")\n",
82+
"\n",
83+
"\n",
84+
"def _lets_plot_png(plot):\n",
85+
" \"\"\"Render a Lets-Plot spec to PNG so the cell output carries an image.\"\"\"\n",
86+
" path = ggsave(plot + lp.ggsize(750, 750), \"plot.png\", path=_LETS_PLOT_DIR)\n",
87+
" with open(path, \"rb\") as f:\n",
88+
" return f.read()\n",
89+
"\n",
90+
"\n",
91+
"get_ipython().display_formatter.formatters[\"image/png\"].for_type(\n",
92+
" lp.plot.core.PlotSpec, _lets_plot_png\n",
93+
")"
94+
]
995
},
1096
{
1197
"cell_type": "code",
@@ -291,6 +377,26 @@
291377
")"
292378
]
293379
},
380+
{
381+
"cell_type": "code",
382+
"execution_count": null,
383+
"metadata": {
384+
"tags": [
385+
"ex",
386+
"name:bar-counts",
387+
"package:seaborn-objects"
388+
]
389+
},
390+
"outputs": [],
391+
"source": [
392+
"\"\"\"seaborn.objects has no `coord_flip`, so the\n",
393+
"categorical variable is mapped to `y` instead.\n",
394+
"\"\"\"\n",
395+
"(so.Plot(mpg, y=\"manufacturer\")\n",
396+
" .add(so.Bar(), so.Count())\n",
397+
" .label(title=\"Number of Cars by Make\"))"
398+
]
399+
},
294400
{
295401
"cell_type": "markdown",
296402
"metadata": {},
@@ -423,6 +529,22 @@
423529
")"
424530
]
425531
},
532+
{
533+
"cell_type": "code",
534+
"execution_count": null,
535+
"metadata": {
536+
"tags": [
537+
"ex",
538+
"name:simple-histogram",
539+
"package:seaborn-objects"
540+
]
541+
},
542+
"outputs": [],
543+
"source": [
544+
"(so.Plot(mpg, x=\"cty\")\n",
545+
" .add(so.Bars(), so.Hist(binwidth=2)))"
546+
]
547+
},
426548
{
427549
"cell_type": "markdown",
428550
"metadata": {},
@@ -558,6 +680,26 @@
558680
")"
559681
]
560682
},
683+
{
684+
"cell_type": "code",
685+
"execution_count": null,
686+
"metadata": {
687+
"tags": [
688+
"ex",
689+
"name:scatter-plot",
690+
"package:seaborn-objects"
691+
]
692+
},
693+
"outputs": [],
694+
"source": [
695+
"(so.Plot(mpg, x=\"displ\", y=\"hwy\")\n",
696+
" .add(so.Dot())\n",
697+
" .label(\n",
698+
" x=\"Engine Displacement in Liters\",\n",
699+
" y=\"Highway MPG\",\n",
700+
" title=\"Engine Displacement in Liters vs Highway MPG\"))"
701+
]
702+
},
561703
{
562704
"cell_type": "markdown",
563705
"metadata": {},
@@ -819,6 +961,27 @@
819961
"));"
820962
]
821963
},
964+
{
965+
"cell_type": "code",
966+
"execution_count": null,
967+
"metadata": {
968+
"tags": [
969+
"ex",
970+
"name:scatter-plot-with-colors",
971+
"package:seaborn-objects"
972+
]
973+
},
974+
"outputs": [],
975+
"source": [
976+
"(so.Plot(mpg, x=\"displ\", y=\"hwy\",\n",
977+
" color=\"class\")\n",
978+
" .add(so.Dot())\n",
979+
" .label(\n",
980+
" x=\"Engine Displacement in Liters\",\n",
981+
" y=\"Highway MPG\",\n",
982+
" title=\"Engine Displacement in Liters vs Highway MPG\"))"
983+
]
984+
},
822985
{
823986
"cell_type": "code",
824987
"execution_count": null,
@@ -1017,6 +1180,25 @@
10171180
")"
10181181
]
10191182
},
1183+
{
1184+
"cell_type": "code",
1185+
"execution_count": null,
1186+
"metadata": {
1187+
"tags": [
1188+
"ex",
1189+
"name:scatter-plot-with-size",
1190+
"package:seaborn-objects"
1191+
]
1192+
},
1193+
"outputs": [],
1194+
"source": [
1195+
"(so.Plot(mpg, x=\"cty\", y=\"hwy\",\n",
1196+
" pointsize=\"cyl\")\n",
1197+
" .add(so.Dots(alpha=.5))\n",
1198+
" .scale(pointsize=(4, 12))\n",
1199+
" .label(x=\"City MPG\", y=\"Highway MPG\"))"
1200+
]
1201+
},
10201202
{
10211203
"cell_type": "markdown",
10221204
"metadata": {},
@@ -1085,6 +1267,23 @@
10851267
");"
10861268
]
10871269
},
1270+
{
1271+
"cell_type": "code",
1272+
"execution_count": null,
1273+
"metadata": {
1274+
"tags": [
1275+
"ex",
1276+
"name:scatter-plot-with-facet",
1277+
"package:seaborn-objects"
1278+
]
1279+
},
1280+
"outputs": [],
1281+
"source": [
1282+
"(so.Plot(mpg, x=\"displ\", y=\"hwy\")\n",
1283+
" .add(so.Dot())\n",
1284+
" .facet(\"class\", wrap=4))"
1285+
]
1286+
},
10881287
{
10891288
"cell_type": "code",
10901289
"execution_count": null,
@@ -1211,6 +1410,23 @@
12111410
");"
12121411
]
12131412
},
1413+
{
1414+
"cell_type": "code",
1415+
"execution_count": null,
1416+
"metadata": {
1417+
"tags": [
1418+
"ex",
1419+
"name:scatter-plot-with-facets",
1420+
"package:seaborn-objects"
1421+
]
1422+
},
1423+
"outputs": [],
1424+
"source": [
1425+
"(so.Plot(mpg, x=\"displ\", y=\"hwy\")\n",
1426+
" .add(so.Dot())\n",
1427+
" .facet(col=\"cyl\", row=\"drv\"))"
1428+
]
1429+
},
12141430
{
12151431
"cell_type": "code",
12161432
"execution_count": null,
@@ -1546,6 +1762,22 @@
15461762
")"
15471763
]
15481764
},
1765+
{
1766+
"cell_type": "code",
1767+
"execution_count": null,
1768+
"metadata": {
1769+
"tags": [
1770+
"ex",
1771+
"name:stacked-bar-chart",
1772+
"package:seaborn-objects"
1773+
]
1774+
},
1775+
"outputs": [],
1776+
"source": [
1777+
"(so.Plot(diamonds, x=\"cut\", color=\"clarity\")\n",
1778+
" .add(so.Bar(), so.Count(), so.Stack()))"
1779+
]
1780+
},
15491781
{
15501782
"cell_type": "code",
15511783
"execution_count": null,
@@ -1659,6 +1891,22 @@
16591891
")"
16601892
]
16611893
},
1894+
{
1895+
"cell_type": "code",
1896+
"execution_count": null,
1897+
"metadata": {
1898+
"tags": [
1899+
"ex",
1900+
"name:dodged-bar-chart",
1901+
"package:seaborn-objects"
1902+
]
1903+
},
1904+
"outputs": [],
1905+
"source": [
1906+
"(so.Plot(diamonds, x=\"cut\", color=\"clarity\")\n",
1907+
" .add(so.Bar(), so.Count(), so.Dodge()))"
1908+
]
1909+
},
16621910
{
16631911
"cell_type": "code",
16641912
"execution_count": null,
@@ -1715,6 +1963,27 @@
17151963
"outputs": [],
17161964
"source": "(sns\n .FacetGrid(diamonds, \n hue=\"cut\", \n height=10, \n xlim=(55, 70))\n .map(sns.kdeplot, 'depth', fill=True)\n .add_legend()\n);"
17171965
},
1966+
{
1967+
"cell_type": "code",
1968+
"execution_count": null,
1969+
"metadata": {
1970+
"tags": [
1971+
"ex",
1972+
"name:stacked-kde",
1973+
"package:seaborn-objects"
1974+
]
1975+
},
1976+
"outputs": [],
1977+
"source": [
1978+
"\"\"\"`.limit()` only clips the axis; unlike ggplot2's\n",
1979+
"`xlim()` it does not drop rows before the density is\n",
1980+
"estimated.\n",
1981+
"\"\"\"\n",
1982+
"(so.Plot(diamonds, x=\"depth\", color=\"cut\")\n",
1983+
" .add(so.Area(alpha=.1), so.KDE(gridsize=500))\n",
1984+
" .limit(x=(55, 70)))"
1985+
]
1986+
},
17181987
{
17191988
"cell_type": "code",
17201989
"execution_count": null,
@@ -1901,6 +2170,22 @@
19012170
" x=\"date\", y=\"value\"\n",
19022171
")"
19032172
]
2173+
},
2174+
{
2175+
"cell_type": "code",
2176+
"execution_count": null,
2177+
"metadata": {
2178+
"tags": [
2179+
"ex",
2180+
"name:timeseries",
2181+
"package:seaborn-objects"
2182+
]
2183+
},
2184+
"outputs": [],
2185+
"source": [
2186+
"(so.Plot(ts, x=\"date\", y=\"value\")\n",
2187+
" .add(so.Line()))"
2188+
]
19042189
}
19052190
],
19062191
"metadata": {

INTRO.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ Many excellent plotting tools are built on top of Matplotlib.
2020

2121
"[Seaborn](https://seaborn.pydata.org/ "Seaborn: statistical data visualization") is a Python visualization library based on matplotlib. It provides a high-level interface for drawing attractive statistical graphics." Seaborn makes beautiful plots but is geared toward specific statistical plots, not general purpose plotting. It does have a powerful [faceting utility function](http://seaborn.pydata.org/tutorial/axis_grids.html) that I use regularly.
2222

23+
Seaborn 0.12 added [seaborn.objects](https://seaborn.pydata.org/tutorial/objects_interface.html), a second interface built on the grammar of graphics. It composes a plot from marks and statistical transforms instead of dispatching to a named plotting function, so it covers far more of the examples below than the classic interface does. It has no loess smoother and no regression confidence band, so those two examples are missing.
24+
2325
#### Interactive Plotting Libraries
2426

2527
There are several tools that can make the kinds of plots described here. At present, I have little experience with them. If anyone would like to help add examples, please [get in touch](https://github.com/tdhopper/pythonplot.com).

render.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"pandas": "Pandas",
2121
"matplotlib": "Matplotlib",
2222
"seaborn": "Seaborn",
23+
"seaborn-objects": "seaborn.objects",
2324
"plotnine": "plotnine",
2425
"lets-plot": "lets-plot",
2526
"plotly": "plotly",

0 commit comments

Comments
 (0)