from plotnine import aes, geom_bar, ggplot, labs
from plotnine.data import penguins
import maidr
p = (
ggplot(penguins, aes("species"))
+ geom_bar()
+ labs(title="Penguins per Species", x="Species", y="Penguins")
)
maidr.show(p) plotnine Accessible Plot Examples
plotnine Examples
maidr also supports plotnine, the Python implementation of ggplot2’s grammar of graphics. Pass a ggplot to maidr.show(), maidr.render() or maidr.save_html(), and maidr produces a page where the chart can be read from the keyboard, as sound, as text and in braille – what maidr for R does for ggplot2 itself. For the other libraries, see the Matplotlib / Seaborn, Plotly, Bokeh and Altair pages.
plotnine support is experimental. What it reads, and how, may change without a deprecation period, whichever plot type is drawn: see Plot Type Stability. Install it with pip install "maidr[plotnine]".
maidr reads each layer’s own data as plotnine computed it – after the stat, the position adjustment and the scales – rather than the shapes it drew, so a count is the count stat_count made, a stacked segment is announced with its own value, and a box with the five numbers stat_boxplot computed. Each facet panel is a subplot. As you move through a chart, the mark being read is outlined on the plotnine drawing itself.
| plotnine | read as |
|---|---|
geom_bar, geom_col, one bar per category |
bar |
geom_bar, geom_col with position="stack" (the default) |
stacked bar |
geom_bar, geom_col with position="dodge" |
dodged bar |
geom_histogram |
histogram |
geom_point |
point |
geom_line |
line, one series per group |
geom_smooth |
smooth, with its confidence band |
geom_boxplot |
box |
geom_tile with a numeric fill |
heatmap |
facet_wrap, facet_grid |
one subplot per panel |
geom_bar, geom_col with position="fill" |
normalized stacked bar [experimental] |
Any other geom, a jittered point, or a chart on a coordinate system other than coord_cartesian is left out with a warning naming it, and a chart with nothing maidr can read is shown as a static image. Use maidr.show(p) rather than plotnine’s own p.show() or a notebook’s display of p: those draw the chart as an ordinary matplotlib figure, which maidr cannot read beyond its points.
Bar Plot
Stacked Bar Plot
from plotnine import aes, geom_bar, ggplot, labs
from plotnine.data import penguins
import maidr
p = (
ggplot(penguins, aes("species", fill="island"))
+ geom_bar()
+ labs(title="Penguins per Species and Island", x="Species", y="Penguins")
)
maidr.show(p) Each segment is announced with its own count, not the height of the stack it sits on, and a species with no penguins on an island is announced as missing rather than as zero. The series run from the bottom of the stack up.
Dodged (Grouped) Bar Plot
from plotnine import aes, geom_bar, ggplot, labs
from plotnine.data import penguins
import maidr
p = (
ggplot(penguins.dropna(subset=["sex"]), aes("species", fill="sex"))
+ geom_bar(position="dodge")
+ labs(title="Penguins per Species and Sex", x="Species", y="Penguins")
)
maidr.show(p) Histogram
from plotnine import aes, geom_histogram, ggplot, labs
from plotnine.data import penguins
import maidr
p = (
ggplot(penguins.dropna(subset=["body_mass_g"]), aes("body_mass_g"))
+ geom_histogram(bins=20)
+ labs(title="Penguin Body Mass", x="Body Mass (g)", y="Penguins")
)
maidr.show(p) Scatter Plot
from plotnine import aes, geom_point, ggplot, labs
from plotnine.data import mtcars
import maidr
p = (
ggplot(mtcars, aes("hp", "mpg"))
+ geom_point()
+ labs(title="Fuel Economy and Power", x="Horsepower", y="Miles per Gallon")
)
maidr.show(p) Line Plot
from plotnine import aes, geom_line, ggplot, labs
from plotnine.data import economics
import maidr
recent = economics[economics["date"].dt.year >= 2000]
p = (
ggplot(recent, aes("date", "unemploy"))
+ geom_line()
+ labs(title="US Unemployment", x="Month", y="Unemployed (thousands)")
)
maidr.show(p) Multi-Line Plot
from plotnine import aes, geom_line, ggplot, labs
from plotnine.data import economics_long
import maidr
two = economics_long[
economics_long["variable"].isin(["psavert", "uempmed"])
& (economics_long["date"].dt.year >= 2000)
]
p = (
ggplot(two, aes("date", "value", color="variable"))
+ geom_line()
+ labs(title="Savings Rate and Unemployment Duration", x="Month", y="Value")
)
maidr.show(p) Each colour is one series, named by its value of the variable color maps.
Box Plot
from plotnine import aes, geom_boxplot, ggplot, labs
from plotnine.data import penguins
import maidr
p = (
ggplot(penguins.dropna(subset=["body_mass_g"]), aes("species", "body_mass_g"))
+ geom_boxplot()
+ labs(title="Body Mass by Species", x="Species", y="Body Mass (g)")
)
maidr.show(p) Heatmap
from plotnine import aes, geom_tile, ggplot, guide_colorbar, guides, labs
from plotnine.data import penguins
import maidr
means = (
penguins.groupby(["species", "island"], observed=True)["body_mass_g"]
.mean()
.round()
.reset_index()
)
p = (
ggplot(means, aes("island", "species", fill="body_mass_g"))
+ geom_tile()
+ guides(fill=guide_colorbar(display="rectangles"))
+ labs(title="Mean Body Mass (g)", x="Island", y="Species", fill="Body Mass (g)")
)
maidr.show(p) Each cell is announced with the value fill maps, not its colour. A species never recorded on an island has no tile, and is announced as missing.
guide_colorbar(display="rectangles") draws the colour bar as a stack of rectangles. plotnine’s default gradient is written to SVG as thousands of shaded triangles, which makes this one chart close to 2 MB; the rectangles look the same and weigh a few tens of kilobytes.
Scatter Plot with a Smooth
from plotnine import aes, geom_point, geom_smooth, ggplot, labs
from plotnine.data import mtcars
import maidr
p = (
ggplot(mtcars, aes("wt", "mpg"))
+ geom_point()
+ geom_smooth(method="lm")
+ labs(title="Fuel Economy and Weight", x="Weight (1000 lb)",
y="Miles per Gallon")
)
maidr.show(p) The points and the fitted line are two layers of one subplot; the line carries the bounds of its confidence band at every point.
Faceted Plot
from plotnine import aes, facet_wrap, geom_point, ggplot, labs
from plotnine.data import mtcars
import maidr
p = (
ggplot(mtcars, aes("wt", "mpg"))
+ geom_point()
+ facet_wrap("cyl")
+ labs(title="Fuel Economy by Cylinders", x="Weight (1000 lb)",
y="Miles per Gallon")
)
maidr.show(p) Each panel is a subplot, titled by its facet as cyl = 4. Press Enter to go into one, Escape to come back out, and the arrow keys between them, in the directions they are laid out on the page.
Normalized Stacked Bar Plot [experimental]
from plotnine import aes, geom_bar, ggplot, labs
from plotnine.data import penguins
import maidr
p = (
ggplot(penguins, aes("island", fill="species"))
+ geom_bar(position="fill")
+ labs(title="Species Share on Each Island", x="Island", y="Share")
)
maidr.show(p) Each segment is announced as its share of the bar, so the segments of one bar add up to 1.
Saving and embedding
maidr.save_html(p, "chart.html") writes the same page to a file, and maidr.render(p) returns it as HTML for a Shiny or Streamlit app. plotnine draws through matplotlib, so use_cdn behaves exactly as it does for a matplotlib figure, and use_cdn=False gives a page that works offline.