from plotnine import (
ggplot,
aes,
geom_point,
geom_boxplot,
geom_bar,
geom_smooth,
facet_wrap,
labs,
theme,
theme_538,
element_rect,
element_text,
)
from plotnine import *
from plotnine.composition import plot_spacer
from plotnine.data import mtcarsPlots
In [1]:
In [2]:
p1 = ggplot(mtcars, aes("disp", "qsec")) + geom_smooth()
p2 = ggplot(mtcars, aes("wt", "mpg")) + geom_point()
p3 = ggplot(mtcars, aes("factor(gear)", "mpg")) + geom_boxplot()
p4 = ggplot(mtcars, aes("carb")) + geom_bar()The Arithmetic
In [3]:
(p1 | p2 | p3) / p4
In [4]:
(p1 / p2 / p3) | p4
The grouping of the plots is determined by the precedence of the operators which means these two:
p1 / p2 / p3 | p4
(p1 / p2 / p3) | p4are equivalent.
The space allocated within the overall composition is determined by the groups. e.g. Below, the panel in p1 has the same height as the panels of p2 and p3 combined.
In [5]:
(p1 / (p2 / p3)) | p4
In [6]:
p1 | (p2 / p3) | p4
For a 2x wider panel on the left, we group the items on the right.
In [7]:
p1 | ((p2 / p3) | p4)
For a 2x wider panel on the right, we put together the left and right at the same nesting level.
In [8]:
(p1 | (p2 / p3)) - p4
Modifying the composition
Add to the last plot in the composition
When an object that is not a plot or composition is added (+) to the composition, it is added (+) to the last plot in the composition.
In [9]:
composition = (p1 | (p2 / p3) | p4)
composition + theme_bw()
The dpi and figure_size of the composition are taken from the last plot, so we can add to the composition to change them.
In [10]:
composition + theme(figure_size=(4, 3))
In [11]:
composition + geom_line(aes(y=after_stat("count")), stat="count", color="cyan")
Add to plots at the top level of the composition
In [12]:
composition * theme_bw()
Add to all plots in the composition
In [13]:
composition & theme_bw()
Adding space to the composition
You can create space within the composition by adding a plot_spacer or by adjusting plot_margin.
In [14]:
p1 | p2
In [15]:
p1 | plot_spacer() | p2
In [16]:
p1 | (p2 + theme(plot_margin_left=.25))
In [17]:
p1 | (p2 + theme(plot_margin_right=.25))
In [18]:
p1 | (p2 + theme(plot_margin_bottom=.25))
While the margin is added to p2, the height of p1 is adjusted so that the panels align.
How space is allocated
For any composition group, the space is allocated such that the edges of the panels align along one dimension, and the sizes are equal along the other dimension. For example, when a plot has a legend, it is allocated more space so that its panel has the same size as the adjacent panel.
In [19]:
p1 | p2 + aes(color="factor(cyl)")
Making the plot backgrounds visible reveals the size of each plot.
In [20]:
brown_bg = theme(plot_background=element_rect(fill="#FF000022"))
cyan_bg = theme(plot_background=element_rect(fill="#00FF0022"))
(p1 + brown_bg) | (p2 + aes(color="factor(cyl)") + cyan_bg)
Facetted plots are treated as if all the panels were one.
In [21]:
p1 | (p2 + aes(color="factor(cyl)") + facet_wrap("cyl", ncol=1))
And the space between the facet panels counts towards the panel area of the plot.
In [22]:
p1 | (p2 + aes(color="factor(cyl)") + facet_wrap("cyl", ncol=2))
Tagging Plots
Tags are an essential part of plot compositions and the by default the are placed in the top-left margin of each plot.
In [23]:
p1_a = p1 + labs(tag="a)")
p2_b = p2 + labs(tag="b)")
p3_c = p3 + labs(tag="c)")
p4_d = p4 + labs(tag="d)")
(p1_a | p2_b | p3_c) / p4_d
The position of each tag can be changed.
In [24]:
top_right = theme(plot_tag_position="topright")
top = theme(plot_tag_position="top")
p1_a = p1 + labs(tag="a)") + top_right
p2_b = p2 + labs(tag="b)") + top_right
p3_c = p3 + labs(tag="c)") + top_right
p4_d = p4 + labs(tag="d)") + top
(p1_a | p2_b | p3_c) / p4_d
You can also set the location to one of margin (the default), panel, plot.
In [25]:
panel_top_right = theme(
plot_tag_position="topright",
plot_tag_location="panel",
plot_tag=element_text(color="brown", margin={"t": 2, "r": 2})
)
p1_a = p1 + labs(tag="a)") + panel_top_right
p2_b = p2 + labs(tag="b)") + panel_top_right
p3_c = p3 + labs(tag="c)") + panel_top_right
p4_d = p4 + labs(tag="d)") + panel_top_right
(p1_a | p2_b | p3_c) / p4_d
The valid positions for tags are topleft, top, topright, right, bottomright, bottom, bottomleft, left or a tuple[float, float].
Save
Use the save method to save the composition as an image e.g.
composition.save("plot.png")
composition.save("plot.png", dpi=200)
composition.save("plot.jpg")
composition.save("plot.svg")
composition.save("plot.pdf")