ninejs
Bringing ✨interactivity✨ to plotnine.
ninejs adds interactive behavior to plotnine charts with a minimal, composable API. You can attach tooltips, hover grouping, and other frontend interactions directly from aes(), then export the result as a standalone HTML plot.
It works out of the box with Quarto, marimo, and Shiny, and it includes a built-in preview in Positron.
Quick start¶
Specify the tooltip and data_id aesthetic mappings, and then pass your plotnine chart to interactive():
from plotnine import ggplot, aes, geom_point, theme_minimal
from plotnine.data import anscombe_quartet
from ninejs import interactive, css, save
gg = (
ggplot(
data=anscombe_quartet,
mapping=aes(x="x", y="y", color="dataset", tooltip="dataset", data_id="dataset"),
)
+ geom_point(size=7, alpha=0.5)
+ theme_minimal()
)
(
interactive(gg)
+ css(from_dict={".tooltip": {"font-size": "3em"}})
+ save("docs/iframes/quickstart2.html")
)
Installation¶
Examples¶
from plotnine import ggplot, aes, geom_point, theme_minimal
from plotnine.data import anscombe_quartet
from ninejs import interactive, css, save
gg = (
ggplot(data=anscombe_quartet, mapping=aes(x="x", y="y", tooltip="dataset"))
+ geom_point(size=7, alpha=0.5)
+ theme_minimal()
)
(
interactive(gg)
+ css(".tooltip {font-size: 2em;}")
+ save("docs/iframes/point.html")
)
from plotnine import ggplot, aes, geom_point, theme_minimal
from plotnine.data import anscombe_quartet
from ninejs import interactive, css, save
gg = (
ggplot(
data=anscombe_quartet,
mapping=aes(x="x", y="y", color="dataset", tooltip="dataset", data_id="dataset"),
)
+ geom_point(size=7, alpha=0.5)
+ theme_minimal()
)
(
interactive(gg)
+ css(from_dict={".tooltip": {"font-size": "3em"}})
+ save("docs/iframes/quickstart2.html")
)
plot = (
ggplot(anscombe_quartet, aes("x", "y", tooltip="x"))
+ geom_point(color="sienna", fill="orange", size=3)
+ geom_smooth(method="lm", se=False, fullrange=True, color="steelblue", size=1)
+ facet_wrap("dataset")
+ labs(title="Anscombe’s Quartet")
+ scale_y_continuous(breaks=(4, 8, 12))
+ coord_fixed(xlim=(3, 22), ylim=(2, 14))
+ theme_tufte(base_family="Futura", base_size=16)
+ theme(
axis_line=element_line(color="#4d4d4d"),
axis_ticks_major=element_line(color="#00000000"),
axis_title=element_blank(),
panel_spacing=0.09,
)
)
interactive(plot) + save("docs/iframes/facet_wrap.html")