Comprehensive Python library for creating static, animated, and interactive visualizations
—
Direct manipulation of Figure and Axes objects provides maximum control and flexibility. This approach is recommended for complex layouts, programmatic plot generation, and when building reusable plotting functions.
The object-oriented API centers on two main classes:
Top-level container managing the entire plot canvas.
from matplotlib.figure import Figure
class Figure:
def __init__(self, figsize=None, dpi=None, facecolor=None,
edgecolor=None, linewidth=0.0, frameon=None,
subplotpars=None, tight_layout=None, constrained_layout=None,
layout=None, **kwargs):
"""Create a new figure."""
def add_subplot(self, nrows=1, ncols=1, index=1, **kwargs) -> Axes:
"""Add an Axes to the figure as part of a subplot arrangement."""
def add_axes(self, rect, projection=None, polar=False, **kwargs) -> Axes:
"""Add an Axes to the figure."""
def add_gridspec(self, nrows=1, ncols=1, **kwargs) -> GridSpec:
"""Return a GridSpec that has this figure as a parent."""
def add_subfigure(self, subplotspec, **kwargs) -> SubFigure:
"""Add a SubFigure to the figure as part of a subplot arrangement."""
def delaxes(self, ax) -> None:
"""Remove the Axes ax from the figure."""
def clear(self, keep_observers=False) -> None:
"""Clear the figure."""
def draw(self, renderer) -> None:
"""Draw the Artist (and its children) using the given renderer."""
def savefig(self, fname, *, transparent=None, **kwargs) -> None:
"""Save the current figure."""
def show(self, warn=True) -> None:
"""If using a GUI backend, display the figure window."""
def tight_layout(self, *, pad=1.08, h_pad=None, w_pad=None, rect=None) -> None:
"""Adjust the padding between and around subplots."""
def suptitle(self, t, **kwargs) -> Text:
"""Add a centered suptitle to the figure."""
def text(self, x, y, s, **kwargs) -> Text:
"""Add text to the figure."""
def get_axes(self) -> list:
"""Return a list of axes in the Figure."""
def get_size_inches(self) -> tuple:
"""Return the current size of the figure in inches."""
def set_size_inches(self, w, h=None, forward=True) -> None:
"""Set the figure size in inches."""Individual plotting area containing the actual data visualization.
from matplotlib.axes import Axes
class Axes:
# Plotting methods
def plot(self, *args, scalex=True, scaley=True, data=None, **kwargs) -> list:
"""Plot y versus x as lines and/or markers."""
def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
vmin=None, vmax=None, alpha=None, linewidths=None,
edgecolors=None, plotnonfinite=False, **kwargs) -> PathCollection:
"""A scatter plot of y vs. x with varying marker size and/or color."""
def bar(self, x, height, width=0.8, bottom=None, *, align='center',
data=None, **kwargs) -> BarContainer:
"""Make a bar plot."""
def barh(self, y, width, height=0.8, left=None, *, align='center',
data=None, **kwargs) -> BarContainer:
"""Make a horizontal bar plot."""
def hist(self, x, bins=None, range=None, density=False, weights=None,
cumulative=False, bottom=None, histtype='bar', align='mid',
orientation='vertical', rwidth=None, log=False, color=None,
label=None, stacked=False, **kwargs) -> tuple:
"""Compute and plot a histogram."""
def pie(self, x, explode=None, labels=None, colors=None, autopct=None,
pctdistance=0.6, shadow=False, labeldistance=1.1,
startangle=0, radius=1, counterclock=True, wedgeprops=None,
textprops=None, center=(0, 0), frame=False, rotatelabels=False,
normalize=True, **kwargs) -> tuple:
"""Plot a pie chart."""
def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
positions=None, widths=None, patch_artist=None,
bootstrap=None, usermedians=None, conf_intervals=None,
meanline=None, showmeans=None, showcaps=None,
showbox=None, showfliers=None, boxprops=None,
labels=None, flierprops=None, medianprops=None,
meanprops=None, capprops=None, whiskerprops=None,
manage_ticks=True, autorange=False, zorder=None,
capwidths=None, **kwargs) -> dict:
"""Make a box and whisker plot."""
def violinplot(self, dataset, positions=None, vert=True, widths=0.5,
showmeans=False, showextrema=True, showmedians=False,
quantiles=None, points=100, bw_method=None, **kwargs) -> dict:
"""Make a violin plot."""
def errorbar(self, x, y, yerr=None, xerr=None, fmt='', ecolor=None,
elinewidth=None, capsize=None, barsabove=False,
lolims=False, uplims=False, xlolims=False, xuplims=False,
errorevery=1, capthick=None, **kwargs) -> ErrorbarContainer:
"""Plot y versus x with error bars."""
# 2D plotting methods
def imshow(self, X, cmap=None, norm=None, aspect=None, interpolation=None,
alpha=None, vmin=None, vmax=None, origin=None, extent=None,
filternorm=True, filterrad=4.0, resample=None, url=None,
**kwargs) -> AxesImage:
"""Display data as an image, i.e., on a 2D regular raster."""
def contour(self, X, Y, Z, levels=None, **kwargs) -> QuadContourSet:
"""Draw contour lines."""
def contourf(self, X, Y, Z, levels=None, **kwargs) -> QuadContourSet:
"""Draw filled contours."""
def pcolormesh(self, X, Y, C, **kwargs) -> QuadMesh:
"""Create a pseudocolor plot with a non-regular rectangular grid."""
def quiver(self, X, Y, U, V, C=None, **kwargs) -> Quiver:
"""Plot a 2D field of arrows."""
# Labeling and annotation methods
def set_xlabel(self, xlabel, fontdict=None, labelpad=None, *,
loc=None, **kwargs) -> Text:
"""Set the label for the x-axis."""
def set_ylabel(self, ylabel, fontdict=None, labelpad=None, *,
loc=None, **kwargs) -> Text:
"""Set the label for the y-axis."""
def set_title(self, label, fontdict=None, loc=None, pad=None, *,
y=None, **kwargs) -> Text:
"""Set a title for the Axes."""
def text(self, x, y, s, fontdict=None, **kwargs) -> Text:
"""Add text to the Axes."""
def annotate(self, text, xy, xytext=None, xycoords='data', textcoords=None,
arrowprops=None, annotation_clip=None, **kwargs) -> Annotation:
"""Annotate the point xy with text."""
def legend(self, *args, **kwargs) -> Legend:
"""Place a legend on the Axes."""
# Axis control methods
def set_xlim(self, left=None, right=None, *, emit=True, auto=False,
xmin=None, xmax=None) -> tuple:
"""Set the x-axis view limits."""
def set_ylim(self, bottom=None, top=None, *, emit=True, auto=False,
ymin=None, ymax=None) -> tuple:
"""Set the y-axis view limits."""
def get_xlim(self) -> tuple:
"""Return the x-axis view limits."""
def get_ylim(self) -> tuple:
"""Return the y-axis view limits."""
def set_xscale(self, value, **kwargs) -> None:
"""Set the x-axis scale."""
def set_yscale(self, value, **kwargs) -> None:
"""Set the y-axis scale."""
def grid(self, visible=None, which='major', axis='both', **kwargs) -> None:
"""Configure the grid lines."""
def set_xticks(self, ticks, labels=None, *, minor=False, **kwargs) -> list:
"""Set the xaxis' tick locations and optionally labels."""
def set_yticks(self, ticks, labels=None, *, minor=False, **kwargs) -> list:
"""Set the yaxis' tick locations and optionally labels."""
def tick_params(self, axis='both', **kwargs) -> None:
"""Change the appearance of ticks, tick labels, and gridlines."""
# Layout and appearance methods
def clear(self) -> None:
"""Clear the Axes."""
def cla(self) -> None:
"""Clear the Axes."""
def set_aspect(self, aspect, adjustable=None, anchor=None, share=False) -> None:
"""Set the aspect ratio of the axes scaling."""
def margins(self, *margins, x=None, y=None, tight=True) -> tuple:
"""Set or retrieve autoscaling margins."""
def invert_xaxis(self) -> None:
"""Invert the x-axis."""
def invert_yaxis(self) -> None:
"""Invert the y-axis."""Various ways to create subplot layouts.
from matplotlib.gridspec import GridSpec
class GridSpec:
def __init__(self, nrows, ncols, figure=None, left=None, bottom=None,
right=None, top=None, wspace=None, hspace=None,
width_ratios=None, height_ratios=None):
"""Create a GridSpec."""
def __getitem__(self, key) -> SubplotSpec:
"""Create and return a SubplotSpec instance."""
def subplot_mosaic(mosaic, *, sharex=False, sharey=False, width_ratios=None,
height_ratios=None, empty_sentinel='.', subplot_kw=None,
gridspec_kw=None, **fig_kw) -> tuple:
"""Build a layout of Axes based on ASCII art or nested lists."""from matplotlib.figure import Figure
import numpy as np
# Create figure and axes
fig = Figure(figsize=(10, 6))
ax = fig.add_subplot(111)
# Generate data and plot
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
ax.plot(x, y, 'b-', linewidth=2, label='sin(x)')
ax.set_xlabel('X values')
ax.set_ylabel('Y values')
ax.set_title('Sine Wave')
ax.legend()
ax.grid(True)
# Save or display
fig.savefig('sine_wave.png', dpi=300, bbox_inches='tight')from matplotlib.figure import Figure
from matplotlib.gridspec import GridSpec
import numpy as np
# Create figure with custom layout
fig = Figure(figsize=(12, 8))
gs = GridSpec(3, 3, figure=fig, hspace=0.3, wspace=0.3)
# Create different sized subplots
ax1 = fig.add_subplot(gs[0, :]) # Top row, all columns
ax2 = fig.add_subplot(gs[1, 0]) # Middle left
ax3 = fig.add_subplot(gs[1, 1:]) # Middle right (2 columns)
ax4 = fig.add_subplot(gs[2, :]) # Bottom row, all columns
# Plot different data in each subplot
x = np.linspace(0, 10, 100)
ax1.plot(x, np.sin(x))
ax1.set_title('Main Plot')
ax2.scatter(x[::10], np.cos(x[::10]))
ax2.set_title('Scatter')
ax3.bar(range(5), [1, 3, 2, 5, 4])
ax3.set_title('Bar Chart')
ax4.hist(np.random.normal(0, 1, 1000), bins=30)
ax4.set_title('Histogram')
fig.suptitle('Complex Layout Example')from matplotlib.figure import Figure
import numpy as np
def create_comparison_plot(datasets, labels, title="Comparison"):
"""Create a multi-panel comparison plot."""
n_datasets = len(datasets)
fig = Figure(figsize=(4*n_datasets, 6))
for i, (data, label) in enumerate(zip(datasets, labels)):
ax = fig.add_subplot(1, n_datasets, i+1)
# Plot histogram and line plot
ax.hist(data, bins=30, alpha=0.7, density=True, label='Histogram')
# Add statistics
mean_val = np.mean(data)
std_val = np.std(data)
ax.axvline(mean_val, color='red', linestyle='--',
label=f'Mean: {mean_val:.2f}')
ax.axvline(mean_val + std_val, color='orange', linestyle='--', alpha=0.7)
ax.axvline(mean_val - std_val, color='orange', linestyle='--', alpha=0.7)
ax.set_title(f'{label}\\n(μ={mean_val:.2f}, σ={std_val:.2f})')
ax.legend()
ax.grid(True, alpha=0.3)
fig.suptitle(title)
return fig
# Usage
data1 = np.random.normal(0, 1, 1000)
data2 = np.random.normal(2, 1.5, 1000)
data3 = np.random.exponential(1, 1000)
fig = create_comparison_plot(
[data1, data2, data3],
['Normal(0,1)', 'Normal(2,1.5)', 'Exponential(1)'],
'Distribution Comparison'
)from matplotlib.figure import Figure
from matplotlib.patches import Rectangle, Circle
from matplotlib.lines import Line2D
import numpy as np
fig = Figure(figsize=(10, 8))
ax = fig.add_subplot(111)
# Add custom shapes
rect = Rectangle((0.2, 0.2), 0.3, 0.4, facecolor='lightblue',
edgecolor='blue', linewidth=2)
ax.add_patch(rect)
circle = Circle((0.7, 0.7), 0.1, facecolor='lightcoral',
edgecolor='red', linewidth=2)
ax.add_patch(circle)
# Add custom line
line_x = np.linspace(0, 1, 10)
line_y = 0.5 + 0.2 * np.sin(2 * np.pi * line_x * 3)
line = Line2D(line_x, line_y, color='green', linewidth=3,
linestyle='--', marker='o', markersize=8)
ax.add_line(line)
# Configure axes
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_aspect('equal')
ax.set_title('Custom Artists Example')
ax.grid(True, alpha=0.3)Install with Tessl CLI
npx tessl i tessl/pypi-matplotlib