A Grammar of Graphics for Python providing a declarative approach to data visualization similar to R's ggplot2
—
Themes control the non-data aspects of your plot including colors, fonts, grid lines, backgrounds, and overall appearance. Plotnine provides built-in themes for common styles and comprehensive theming functions for fine-grained customization. Theme elements allow precise control over every visual aspect of your plots.
Ready-to-use themes that provide consistent, professional styling for different contexts.
def theme_gray():
"""
Default gray theme with gray background and white grid lines.
Professional appearance suitable for most contexts.
"""
def theme_grey():
"""
Alias for theme_gray() (British spelling).
"""
def theme_bw():
"""
Black and white theme with white background and gray grid lines.
Clean, high-contrast appearance ideal for publications.
"""
def theme_minimal():
"""
Minimal theme with white background and minimal grid lines.
Clean, modern appearance that emphasizes the data.
"""
def theme_classic():
"""
Classic theme with white background and no grid lines.
Traditional statistical plot appearance.
"""
def theme_void():
"""
Empty theme with no background, grid, or axes.
Useful for specialized plots or custom annotations.
"""
def theme_dark():
"""
Dark theme with dark background and light text.
Suitable for presentations and digital displays.
"""
def theme_light():
"""
Light theme with light gray background.
Soft appearance that reduces visual fatigue.
"""
def theme_linedraw():
"""
Theme with black lines and white background.
High contrast with prominent grid lines and axes.
"""Themes that emulate popular visualization styles and publications.
def theme_matplotlib():
"""
Theme that mimics matplotlib's default style.
Familiar appearance for matplotlib users.
"""
def theme_seaborn():
"""
Theme inspired by seaborn's default style.
Modern statistical visualization appearance.
"""
def theme_538():
"""
Theme inspired by FiveThirtyEight website style.
Bold, journalistic appearance with strong grid lines.
"""
def theme_tufte():
"""
Theme inspired by Edward Tufte's principles.
Minimalist design that maximizes data-ink ratio.
"""
def theme_xkcd():
"""
Theme that mimics hand-drawn/XKCD comic style.
Playful, informal appearance with irregular lines.
"""Functions for modifying and managing themes globally and locally.
def theme(**kwargs):
"""
Customize theme elements.
Parameters accept theme element objects or None to remove elements.
Text elements:
- plot_title: plot title appearance
- plot_subtitle: plot subtitle appearance
- plot_caption: plot caption appearance
- axis_title: axis title appearance
- axis_title_x, axis_title_y: specific axis titles
- axis_text: axis tick labels
- axis_text_x, axis_text_y: specific axis text
- legend_title: legend title appearance
- legend_text: legend text appearance
- strip_text: facet strip text
- strip_text_x, strip_text_y: specific strip text
Line elements:
- axis_line: axis lines
- axis_line_x, axis_line_y: specific axis lines
- axis_ticks: axis tick marks
- axis_ticks_x, axis_ticks_y: specific axis ticks
- panel_grid: panel grid lines
- panel_grid_major, panel_grid_minor: major/minor grid
- panel_grid_major_x, panel_grid_major_y: specific major grid
- panel_grid_minor_x, panel_grid_minor_y: specific minor grid
Rectangle elements:
- plot_background: entire plot background
- panel_background: plot panel background
- legend_background: legend background
- legend_key: legend key background
- strip_background: facet strip background
Spacing and positioning:
- legend_position: legend position ('right', 'left', 'top', 'bottom', 'none')
- legend_direction: legend direction ('horizontal', 'vertical')
- legend_justification: legend anchor point
- legend_margin: space around legend
- panel_spacing: space between panels
- plot_margin: space around entire plot
"""
def theme_get():
"""
Get the current global theme.
Returns:
Current theme object
"""
def theme_set(new_theme):
"""
Set a new global theme.
Parameters:
- new_theme: theme object to set as global default
Returns:
Previous theme object
"""
def theme_update(**kwargs):
"""
Update the current global theme.
Parameters:
- **kwargs: theme elements to modify
Returns:
Updated theme object
"""Building blocks for creating custom theme specifications.
def element_text(family=None, style=None, colour=None, size=None, hjust=None,
vjust=None, angle=None, lineheight=None, color=None, **kwargs):
"""
Text element for theme customization.
Parameters:
- family: str, font family
- style: str, font style ('normal', 'italic')
- colour/color: str, text color
- size: float, text size in points
- hjust: float, horizontal justification (0=left, 0.5=center, 1=right)
- vjust: float, vertical justification (0=bottom, 0.5=middle, 1=top)
- angle: float, text rotation angle in degrees
- lineheight: float, line spacing multiplier
- **kwargs: additional matplotlib text properties
"""
def element_line(colour=None, size=None, linetype=None, color=None, **kwargs):
"""
Line element for theme customization.
Parameters:
- colour/color: str, line color
- size: float, line width in points
- linetype: str, line style ('solid', 'dashed', 'dotted', etc.)
- **kwargs: additional matplotlib line properties
"""
def element_rect(fill=None, colour=None, size=None, linetype=None, color=None,
**kwargs):
"""
Rectangle element for theme customization.
Parameters:
- fill: str, fill color
- colour/color: str, border color
- size: float, border width
- linetype: str, border line style
- **kwargs: additional matplotlib patch properties
"""
def element_blank():
"""
Blank element that removes the theme component entirely.
Use this to hide specific plot elements.
"""# Apply a complete theme
ggplot(data, aes(x='x', y='y')) + \
geom_point() + \
theme_minimal()
# Multiple themes can be layered (later ones override earlier ones)
ggplot(data, aes(x='x', y='y')) + \
geom_point() + \
theme_bw() + \
theme(legend_position='bottom')# Customize plot title and axis labels
ggplot(data, aes(x='x', y='y')) + \
geom_point() + \
theme_minimal() + \
theme(
plot_title=element_text(size=16, hjust=0.5, colour='blue'),
axis_title=element_text(size=12, colour='darkgray'),
axis_text=element_text(size=10, angle=45)
)# Custom panel appearance
ggplot(data, aes(x='x', y='y')) + \
geom_point() + \
theme(
panel_background=element_rect(fill='lightgray'),
panel_grid_major=element_line(colour='white', size=0.5),
panel_grid_minor=element_blank(),
plot_background=element_rect(fill='white', colour='black', size=1)
)# Control legend appearance and position
ggplot(data, aes(x='x', y='y', color='group')) + \
geom_point() + \
theme(
legend_position='bottom',
legend_direction='horizontal',
legend_background=element_rect(fill='lightblue', colour='black'),
legend_title=element_text(size=12, colour='darkblue'),
legend_text=element_text(size=10)
)
# Remove legend entirely
ggplot(data, aes(x='x', y='y', color='group')) + \
geom_point() + \
theme(legend_position='none')# Remove specific theme elements
ggplot(data, aes(x='x', y='y')) + \
geom_point() + \
theme_classic() + \
theme(
axis_line=element_blank(), # Remove axis lines
axis_ticks=element_blank(), # Remove tick marks
panel_grid=element_blank() # Remove all grid lines
)# Customize facet strip appearance
ggplot(data, aes(x='x', y='y')) + \
geom_point() + \
facet_wrap('category') + \
theme(
strip_background=element_rect(fill='lightblue', colour='black'),
strip_text=element_text(size=11, colour='darkblue', face='bold')
)# Set a global theme for all subsequent plots
theme_set(theme_minimal())
# Update global theme with custom elements
theme_update(
plot_title=element_text(hjust=0.5),
legend_position='bottom'
)
# All plots will now use these settings by default
plot1 = ggplot(data1, aes(x='x', y='y')) + geom_point()
plot2 = ggplot(data2, aes(x='a', y='b')) + geom_line()# Clean theme for academic publications
publication_theme = theme_bw() + theme(
text=element_text(family='Arial', size=11),
plot_title=element_text(size=14, hjust=0.5),
axis_title=element_text(size=12),
legend_title=element_text(size=11),
legend_text=element_text(size=10),
strip_text=element_text(size=11),
panel_grid_minor=element_blank()
)
ggplot(data, aes(x='x', y='y')) + \
geom_point() + \
publication_theme# High-contrast theme for presentations
presentation_theme = theme_dark() + theme(
text=element_text(colour='white', size=14),
plot_title=element_text(size=18, hjust=0.5),
axis_title=element_text(size=16),
axis_text=element_text(size=12),
legend_text=element_text(size=12),
plot_background=element_rect(fill='black'),
panel_background=element_rect(fill='gray20')
)# Control plot margins and panel spacing
ggplot(data, aes(x='x', y='y')) + \
geom_point() + \
facet_wrap('group') + \
theme(
plot_margin=(1, 1, 1, 1), # top, right, bottom, left margins in cm
panel_spacing=0.5, # space between panels in cm
legend_margin=10 # space around legend in points
)Install with Tessl CLI
npx tessl i tessl/pypi-plotnine