📈 Let's plot with Nextjournal
EDIT. I wasn't aware first, but Lets-plot's main developer already wrote a notebook on the subject. https://nextjournal.com/alshan/lets-plot-quickstart
Lets-plot is a plotting library developed by Jetbrains with the objective of implementing to Python and Kotlin a grammar of graphics similar to the widely popular ggplot2 R library. Python already has great declarative plot packages such as Plotly express, Altair and Plotnine (and others). Lets-plot is designed to be interactive and very close to ggplot2 (although understandably lagging behind in terms of features since it's relatively new).
Working with Lets-plot within Nextjournal didn't work as I expected, but don't worry: easy fixes are coming. While Matplotlib rendered my plots under the Jupyter protocol (the protocol is defined in the Runtime), Lets-plot didn't. Under the Nextjournal protocol, Lets-plot worked but Matplotlib didn't render.
In the aim of working with a single Python runtime, should I adopt Lets-plot and forget about Matplotlib under a Nextjournal protocol, or rather keep Matplotlib and forget Lets-plot under a Jupyter protocol? I contacted Nextjournal's support team, then Andrea Zampino replied that neither is necessary. Let's install lets-plot in two separate runtimes to show how it's done for each protocol.
pip install lets-plot
pip install lets-plot
🦸 Nextjournal support rescuing
Andrea Zampino offered the fixes in a notebook remixed from the one I sent for a support request. For the example, I'm using 🐧 data.
Jupyter protocol
import pandas as pd
penguins = pd.read_csv("https://gist.githubusercontent.com/ryanorsinger/0e223fb35472c40d449cec4c0737008b/raw/e9688a6b1c2806d9f685f8b9524b80def95f7c97/penguins.csv")
penguins.sample(5)
If you like the imperative visualization mode, Matplotlib works directly under the Jupyter protocol.
import matplotlib.pyplot as plt
for i in penguins.species.unique():
penguins_i = penguins.loc[penguins.species == i, :]
plt.plot(penguins_i.bill_length_mm, penguins_i.bill_depth_mm, 'o', label = i)
plt.xlabel("Bill length (mm)")
plt.ylabel("Bill depth (mm)")
plt.legend()
If you prefer working in declarative mode with Lets-plot, you only need to specify lp.LetsPlot.setup_html(isolated_frame=True)
.
import lets_plot as lp
lp.LetsPlot.setup_html(isolated_frame=True)
(
lp.ggplot(penguins, lp.aes(x = 'bill_length_mm', y = 'bill_depth_mm')) +
lp.geom_point(lp.aes(color = 'species'))
)
Nextjournal protocol
import pandas as pd
penguins = pd.read_csv("https://gist.githubusercontent.com/ryanorsinger/0e223fb35472c40d449cec4c0737008b/raw/e9688a6b1c2806d9f685f8b9524b80def95f7c97/penguins.csv")
The Nexjournal protocol will return the Matplotlib object, not the plot. To render the plot, simply add plt.gcf()
- gcf for get current figure.
import matplotlib.pyplot as plt
for i in penguins.species.unique():
penguins_i = penguins.loc[penguins.species == i, :]
plt.plot(penguins_i.bill_length_mm, penguins_i.bill_depth_mm, 'o', label = i)
plt.xlabel("Bill length (mm)")
plt.ylabel("Bill depth (mm)")
plt.legend()
plt.gcf()
As for Lets-plot, it works without LetsPlot.setup_html
.
import lets_plot as lp
(
lp.ggplot(penguins, lp.aes(x = 'bill_length_mm', y = 'bill_depth_mm')) +
lp.geom_point(lp.aes(color = 'species'))
)