Code examples showing how to make plotnine (ggplot2 grammar) bar charts, stacked and dodged bars, histograms, scatter, line, smooth and box plots, heatmaps, faceted plots, precision-recall curves and percentile bands accessible with py-maidr.
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.
WarningExperimental
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]
geom_line, geom_path of recall against precision
precision-recall curve [experimental]
stat_summary(fun_data="median_hilow", geom="ribbon") with its median line
percentile band [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
Show the code
from plotnine import aes, geom_bar, ggplot, labsfrom plotnine.data import penguinsimport maidr p = ( ggplot(penguins, aes("species"))+ geom_bar()+ labs(title="Penguins per Species", x="Species", y="Penguins"))maidr.show(p)
Bar chart of the number of penguins of each speciesPenguins per Species
Stacked Bar Plot
Show the code
from plotnine import aes, geom_bar, ggplot, labsfrom plotnine.data import penguinsimport maidr p = ( ggplot(penguins, aes("species", fill="island"))+ geom_bar()+ labs(title="Penguins per Species and Island", x="Species", y="Penguins"))maidr.show(p)
Stacked bar chart of penguins per species, split by islandPenguins per Species and Island
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
Show the code
from plotnine import aes, geom_bar, ggplot, labsfrom plotnine.data import penguinsimport 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)
Grouped bar chart of penguins per species, one bar for each sexPenguins per Species and Sex
Histogram
Show the code
from plotnine import aes, geom_histogram, ggplot, labsfrom plotnine.data import penguinsimport 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)
Histogram of penguin body mass in twenty binsPenguin Body Mass
Scatter Plot
Show the code
from plotnine import aes, geom_point, ggplot, labsfrom plotnine.data import mtcarsimport maidr p = ( ggplot(mtcars, aes("hp", "mpg"))+ geom_point()+ labs(title="Fuel Economy and Power", x="Horsepower", y="Miles per Gallon"))maidr.show(p)
Scatter plot of fuel economy against horsepower for 32 carsFuel Economy and Power
Two lines, the personal savings rate and the median weeks of unemploymentSavings Rate and Unemployment Duration
Each colour is one series, named by its value of the variable color maps.
Box Plot
Show the code
from plotnine import aes, geom_boxplot, ggplot, labsfrom plotnine.data import penguinsimport 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)
Box plots of penguin body mass for each speciesBody Mass by Species
Heatmap
Show the code
from plotnine import aes, geom_tile, ggplot, guide_colorbar, guides, labsfrom plotnine.data import penguinsimport 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)
Heatmap of mean penguin body mass for each species on each islandMean Body Mass (g)
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
Show the code
from plotnine import aes, geom_point, geom_smooth, ggplot, labsfrom plotnine.data import mtcarsimport 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)
Scatter plot of fuel economy against weight for 32 cars with a fitted line and its confidence bandFuel Economy and Weight
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
Show the code
from plotnine import aes, facet_wrap, geom_point, ggplot, labsfrom plotnine.data import mtcarsimport 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)
Three scatter plots side by side, fuel economy against weight for 4-, 6- and 8-cylinder carsFuel Economy by Cylinders
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]
Show the code
from plotnine import aes, geom_bar, ggplot, labsfrom plotnine.data import penguinsimport 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)
Stacked bar chart of the share of each species on each islandSpecies Share on Each Island
Each segment is announced as its share of the bar, so the segments of one bar add up to 1.
Precision-recall curves of a logistic regression and a naive Bayes classifierPrecision-Recall Curves
A geom_line or geom_path whose x is recall and whose y is precision – by the columns it maps or by its axis titles, with every value from 0 to 1 – is read as a precision-recall curve, one curve per group named as the lines of a multi-line plot are, each read from low recall up. Any other geom_path is left out, since a path need not move left to right.
The median of 200 simulated sales paths over twelve months, with the band holding the middle 80% of themSimulated Sales
median_hilow draws the band between the 10th and 90th percentiles of the observations at each month (the middle 95% unless confidence_interval says otherwise), and the line is their median. Together they are one percentile band: each month is entered on the median, announced with the band around it, and Up and Down move to the 90th and 10th percentiles. The band is read only with its median line, from one group per panel on a linear y scale; a ribbon on its own is left out.
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.