Skip to content

Commit 70ff4a1

Browse files
committed
Add lets-plot examples for all 13 plots
Lets-Plot renders to PNG through ggsave; an IPython image/png formatter registered on PlotSpec keeps the example cells free of export boilerplate. It is imported as lp so its ggplot2-style names do not shadow plotnine's.
1 parent 3d37cbe commit 70ff4a1

5 files changed

Lines changed: 335 additions & 13 deletions

File tree

Examples.ipynb

Lines changed: 241 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
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)"
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)"
99
},
1010
{
1111
"cell_type": "code",
@@ -227,6 +227,28 @@
227227
")"
228228
]
229229
},
230+
{
231+
"cell_type": "code",
232+
"execution_count": null,
233+
"metadata": {
234+
"tags": [
235+
"ex",
236+
"name:bar-counts",
237+
"package:lets-plot"
238+
]
239+
},
240+
"outputs": [],
241+
"source": [
242+
"\"\"\"Lets-Plot mirrors the ggplot2 grammar. It is imported as `lp` here\n",
243+
"so its names don't collide with plotnine's.\n",
244+
"\"\"\"\n",
245+
"(lp.ggplot(mpg) +\n",
246+
" lp.aes(x=\"manufacturer\") +\n",
247+
" lp.geom_bar() +\n",
248+
" lp.coord_flip() +\n",
249+
" lp.ggtitle(\"Number of Cars by Make\"))"
250+
]
251+
},
230252
{
231253
"cell_type": "code",
232254
"execution_count": null,
@@ -344,6 +366,23 @@
344366
" geom_histogram(binwidth=2))"
345367
]
346368
},
369+
{
370+
"cell_type": "code",
371+
"execution_count": null,
372+
"metadata": {
373+
"tags": [
374+
"ex",
375+
"name:simple-histogram",
376+
"package:lets-plot"
377+
]
378+
},
379+
"outputs": [],
380+
"source": [
381+
"(lp.ggplot(mpg) +\n",
382+
" lp.aes(x=\"cty\") +\n",
383+
" lp.geom_histogram(binwidth=2))"
384+
]
385+
},
347386
{
348387
"cell_type": "code",
349388
"execution_count": null,
@@ -452,6 +491,26 @@
452491
" ylab(\"Highway MPG\"))"
453492
]
454493
},
494+
{
495+
"cell_type": "code",
496+
"execution_count": null,
497+
"metadata": {
498+
"tags": [
499+
"ex",
500+
"name:scatter-plot",
501+
"package:lets-plot"
502+
]
503+
},
504+
"outputs": [],
505+
"source": [
506+
"(lp.ggplot(mpg) +\n",
507+
" lp.aes(x=\"displ\", y=\"hwy\") +\n",
508+
" lp.geom_point() +\n",
509+
" lp.ggtitle(\"Engine Displacement in Liters vs Highway MPG\") +\n",
510+
" lp.xlab(\"Engine Displacement in Liters\") +\n",
511+
" lp.ylab(\"Highway MPG\"))"
512+
]
513+
},
455514
{
456515
"cell_type": "code",
457516
"execution_count": null,
@@ -543,6 +602,24 @@
543602
" geom_smooth(method=\"lm\"))"
544603
]
545604
},
605+
{
606+
"cell_type": "code",
607+
"execution_count": null,
608+
"metadata": {
609+
"tags": [
610+
"ex",
611+
"name:scatter-with-regression",
612+
"package:lets-plot"
613+
]
614+
},
615+
"outputs": [],
616+
"source": [
617+
"(lp.ggplot(mpg) +\n",
618+
" lp.aes(\"displ\", \"hwy\") +\n",
619+
" lp.geom_point() +\n",
620+
" lp.geom_smooth(method=\"lm\"))"
621+
]
622+
},
546623
{
547624
"cell_type": "code",
548625
"execution_count": null,
@@ -762,6 +839,26 @@
762839
" ylab(\"Highway MPG\"))"
763840
]
764841
},
842+
{
843+
"cell_type": "code",
844+
"execution_count": null,
845+
"metadata": {
846+
"tags": [
847+
"ex",
848+
"name:scatter-plot-with-colors",
849+
"package:lets-plot"
850+
]
851+
},
852+
"outputs": [],
853+
"source": [
854+
"(lp.ggplot(mpg) +\n",
855+
" lp.aes(x=\"displ\", y=\"hwy\", color=\"class\") +\n",
856+
" lp.geom_point() +\n",
857+
" lp.ggtitle(\"Engine Displacement in Liters vs Highway MPG\") +\n",
858+
" lp.xlab(\"Engine Displacement in Liters\") +\n",
859+
" lp.ylab(\"Highway MPG\"))"
860+
]
861+
},
765862
{
766863
"cell_type": "code",
767864
"execution_count": null,
@@ -883,6 +980,23 @@
883980
" geom_point(alpha=.5))"
884981
]
885982
},
983+
{
984+
"cell_type": "code",
985+
"execution_count": null,
986+
"metadata": {
987+
"tags": [
988+
"ex",
989+
"name:scatter-plot-with-size",
990+
"package:lets-plot"
991+
]
992+
},
993+
"outputs": [],
994+
"source": [
995+
"(lp.ggplot(mpg) +\n",
996+
" lp.aes(x=\"cty\", y=\"hwy\", size=\"cyl\") +\n",
997+
" lp.geom_point(alpha=.5))"
998+
]
999+
},
8861000
{
8871001
"cell_type": "code",
8881002
"execution_count": null,
@@ -989,6 +1103,24 @@
9891103
" facet_wrap(\" ~ c\", nrow = 2))"
9901104
]
9911105
},
1106+
{
1107+
"cell_type": "code",
1108+
"execution_count": null,
1109+
"metadata": {
1110+
"tags": [
1111+
"ex",
1112+
"name:scatter-plot-with-facet",
1113+
"package:lets-plot"
1114+
]
1115+
},
1116+
"outputs": [],
1117+
"source": [
1118+
"(lp.ggplot(mpg) +\n",
1119+
" lp.aes(x=\"displ\", y=\"hwy\") +\n",
1120+
" lp.geom_point() +\n",
1121+
" lp.facet_wrap(facets=\"class\", nrow=2))"
1122+
]
1123+
},
9921124
{
9931125
"cell_type": "code",
9941126
"execution_count": null,
@@ -1097,6 +1229,24 @@
10971229
" facet_grid(\"drv ~ cyl\"))"
10981230
]
10991231
},
1232+
{
1233+
"cell_type": "code",
1234+
"execution_count": null,
1235+
"metadata": {
1236+
"tags": [
1237+
"ex",
1238+
"name:scatter-plot-with-facets",
1239+
"package:lets-plot"
1240+
]
1241+
},
1242+
"outputs": [],
1243+
"source": [
1244+
"(lp.ggplot(mpg) +\n",
1245+
" lp.aes(x=\"displ\", y=\"hwy\") +\n",
1246+
" lp.geom_point() +\n",
1247+
" lp.facet_grid(x=\"cyl\", y=\"drv\"))"
1248+
]
1249+
},
11001250
{
11011251
"cell_type": "code",
11021252
"execution_count": null,
@@ -1214,6 +1364,26 @@
12141364
" ))"
12151365
]
12161366
},
1367+
{
1368+
"cell_type": "code",
1369+
"execution_count": null,
1370+
"metadata": {
1371+
"tags": [
1372+
"ex",
1373+
"name:stacked-smooth-line-and-scatter",
1374+
"package:lets-plot"
1375+
]
1376+
},
1377+
"outputs": [],
1378+
"source": [
1379+
"(lp.ggplot(mpg) +\n",
1380+
" lp.aes(x=\"displ\", y=\"hwy\") +\n",
1381+
" lp.geom_point(lp.aes(color=\"class\")) +\n",
1382+
" lp.geom_smooth(data=mpg[mpg[\"class\"] == \"subcompact\"],\n",
1383+
" se=False,\n",
1384+
" method=\"loess\"))"
1385+
]
1386+
},
12171387
{
12181388
"cell_type": "code",
12191389
"execution_count": null,
@@ -1301,6 +1471,23 @@
13011471
" geom_bar())"
13021472
]
13031473
},
1474+
{
1475+
"cell_type": "code",
1476+
"execution_count": null,
1477+
"metadata": {
1478+
"tags": [
1479+
"ex",
1480+
"name:stacked-bar-chart",
1481+
"package:lets-plot"
1482+
]
1483+
},
1484+
"outputs": [],
1485+
"source": [
1486+
"(lp.ggplot(diamonds) +\n",
1487+
" lp.aes(x=\"cut\", fill=\"clarity\") +\n",
1488+
" lp.geom_bar())"
1489+
]
1490+
},
13041491
{
13051492
"cell_type": "code",
13061493
"execution_count": null,
@@ -1415,6 +1602,23 @@
14151602
" geom_bar(position = \"dodge\"))\n"
14161603
]
14171604
},
1605+
{
1606+
"cell_type": "code",
1607+
"execution_count": null,
1608+
"metadata": {
1609+
"tags": [
1610+
"ex",
1611+
"name:dodged-bar-chart",
1612+
"package:lets-plot"
1613+
]
1614+
},
1615+
"outputs": [],
1616+
"source": [
1617+
"(lp.ggplot(diamonds) +\n",
1618+
" lp.aes(x=\"cut\", fill=\"clarity\") +\n",
1619+
" lp.geom_bar(position=\"dodge\"))"
1620+
]
1621+
},
14181622
{
14191623
"cell_type": "code",
14201624
"execution_count": null,
@@ -1530,6 +1734,24 @@
15301734
" geom_density(alpha=0.1))"
15311735
]
15321736
},
1737+
{
1738+
"cell_type": "code",
1739+
"execution_count": null,
1740+
"metadata": {
1741+
"tags": [
1742+
"ex",
1743+
"name:stacked-kde",
1744+
"package:lets-plot"
1745+
]
1746+
},
1747+
"outputs": [],
1748+
"source": [
1749+
"(lp.ggplot(diamonds) +\n",
1750+
" lp.aes(\"depth\", fill=\"cut\", color=\"cut\") +\n",
1751+
" lp.geom_density(alpha=0.1) +\n",
1752+
" lp.xlim(55, 70))"
1753+
]
1754+
},
15331755
{
15341756
"cell_type": "code",
15351757
"execution_count": null,
@@ -1614,6 +1836,23 @@
16141836
" + geom_line())"
16151837
]
16161838
},
1839+
{
1840+
"cell_type": "code",
1841+
"execution_count": null,
1842+
"metadata": {
1843+
"tags": [
1844+
"ex",
1845+
"name:timeseries",
1846+
"package:lets-plot"
1847+
]
1848+
},
1849+
"outputs": [],
1850+
"source": [
1851+
"(lp.ggplot(ts)\n",
1852+
" + lp.aes(\"date\", \"value\")\n",
1853+
" + lp.geom_line())"
1854+
]
1855+
},
16171856
{
16181857
"cell_type": "code",
16191858
"execution_count": null,
@@ -1686,4 +1925,4 @@
16861925
},
16871926
"nbformat": 4,
16881927
"nbformat_minor": 1
1689-
}
1928+
}

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ dependencies = [
1818
"matplotlib>=3.7",
1919
"seaborn>=0.13",
2020
"plotnine>=0.13",
21+
"lets-plot>=4.11",
2122
"plotly>=5.24",
2223
"altair>=5.0",
2324
"vl-convert-python>=1.0", # Required for Altair PNG export

render.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"matplotlib": "Matplotlib",
2222
"seaborn": "Seaborn",
2323
"plotnine": "plotnine",
24+
"lets-plot": "lets-plot",
2425
"plotly": "plotly",
2526
"altair": "Altair",
2627
"ggplot": "ggplot2 (R)",

0 commit comments

Comments
 (0)