Comprehensive Python library for creating static, animated, and interactive visualizations
—
Drawing primitive shapes and complex geometric objects. Matplotlib provides extensive patch classes for creating rectangles, circles, polygons, arrows, and custom geometric shapes with full styling control.
Fundamental geometric shapes for annotations and custom graphics.
import matplotlib.patches as mpatches
class Rectangle:
def __init__(self, xy, width, height, *, angle=0.0, **kwargs):
"""Rectangle patch with bottom-left corner at xy."""
def get_x(self) -> float:
"""Return the left coordinate of the rectangle."""
def get_y(self) -> float:
"""Return the bottom coordinate of the rectangle."""
def get_width(self) -> float:
"""Return the width of the rectangle."""
def get_height(self) -> float:
"""Return the height of the rectangle."""
def set_x(self, x) -> None:
"""Set the left coordinate of the rectangle."""
def set_y(self, y) -> None:
"""Set the bottom coordinate of the rectangle."""
def set_width(self, w) -> None:
"""Set the width of the rectangle."""
def set_height(self, h) -> None:
"""Set the height of the rectangle."""
class Circle:
def __init__(self, xy, radius, **kwargs):
"""Circle patch centered at xy."""
def get_radius(self) -> float:
"""Return the radius of the circle."""
def set_radius(self, radius) -> None:
"""Set the radius of the circle."""
class Ellipse:
def __init__(self, xy, width, height, *, angle=0, **kwargs):
"""Ellipse patch centered at xy."""
def get_width(self) -> float:
"""Return the width of the ellipse."""
def get_height(self) -> float:
"""Return the height of the ellipse."""
class Polygon:
def __init__(self, xy, *, closed=True, **kwargs):
"""General polygon patch from sequence of xy coordinates."""
def get_xy(self) -> np.ndarray:
"""Get the vertices of the polygon."""
def set_xy(self, xy) -> None:
"""Set the vertices of the polygon."""
class RegularPolygon:
def __init__(self, xy, numVertices, radius=5, *, orientation=0, **kwargs):
"""Regular polygon with numVertices sides."""
def get_numVertices(self) -> int:
"""Return the number of vertices."""
def get_radius(self) -> float:
"""Return the radius of the polygon."""
def get_orientation(self) -> float:
"""Return the orientation of the polygon."""More complex geometric shapes for specific use cases.
class Wedge:
def __init__(self, center, r, theta1, theta2, *, width=None, **kwargs):
"""Wedge-shaped patch from center with angular range."""
def get_center(self) -> tuple:
"""Return the center of the wedge."""
def get_radius(self) -> float:
"""Return the radius of the wedge."""
def get_theta1(self) -> float:
"""Return the start angle of the wedge."""
def get_theta2(self) -> float:
"""Return the end angle of the wedge."""
class Arc:
def __init__(self, xy, width, height, *, angle=0, theta1=0, theta2=360, **kwargs):
"""Elliptical arc patch."""
def get_theta1(self) -> float:
"""Return the start angle of the arc."""
def get_theta2(self) -> float:
"""Return the end angle of the arc."""
class PathPatch:
def __init__(self, path, **kwargs):
"""Patch from a matplotlib Path object."""
def get_path(self) -> Path:
"""Return the path of the patch."""
def set_path(self, path) -> None:
"""Set the path of the patch."""Arrows and directional indicators with customizable styling.
class Arrow:
def __init__(self, x, y, dx, dy, *, width=1.0, **kwargs):
"""Simple arrow patch from (x,y) with displacement (dx,dy)."""
def get_x(self) -> float:
"""Return the x coordinate of the arrow base."""
def get_y(self) -> float:
"""Return the y coordinate of the arrow base."""
class FancyArrow:
def __init__(self, x, y, dx, dy, *, width=0.001, length_includes_head=False,
head_width=None, head_length=None, shape='full', overhang=0,
head_starts_at_zero=False, **kwargs):
"""Fancy arrow with customizable head and tail."""
def get_dxy(self) -> tuple:
"""Return the displacement (dx, dy) of the arrow."""
class FancyArrowPatch:
def __init__(self, posA=None, posB=None, *, path=None, arrowstyle='->',
connectionstyle='arc3', patchA=None, patchB=None,
shrinkA=2, shrinkB=2, mutation_scale=20, mutation_aspect=1,
**kwargs):
"""Fancy arrow patch connecting two points with custom styling."""
def set_positions(self, posA, posB) -> None:
"""Set the start and end positions of the arrow."""
def set_arrowstyle(self, arrowstyle=None, **kwargs) -> None:
"""Set the arrow style."""
def set_connectionstyle(self, connectionstyle, **kwargs) -> None:
"""Set the connection style."""Complex patch types for specialized graphics.
class FancyBboxPatch:
def __init__(self, xy, width, height, *, boxstyle='round', **kwargs):
"""Fancy bounding box with various border styles."""
def set_boxstyle(self, boxstyle=None, **kwargs) -> None:
"""Set the box style."""
def get_boxstyle(self) -> BoxStyle:
"""Return the box style."""
class ConnectionPatch:
def __init__(self, xyA, xyB, coordsA, coordsB=None, *,
axesA=None, axesB=None, arrowstyle='-', shrinkA=0, shrinkB=0,
**kwargs):
"""Patch to connect two points, possibly in different coordinate systems."""
def set_xyA(self, xy) -> None:
"""Set the starting point A."""
def set_xyB(self, xy) -> None:
"""Set the ending point B."""
class Shadow:
def __init__(self, patch, ox, oy, *, props=None, **kwargs):
"""Create a shadow effect for another patch."""Style specifications for complex patches.
class BoxStyle:
"""Box styling options for FancyBboxPatch."""
@staticmethod
def Round(pad=0.3, rounding_size=None) -> BoxStyle:
"""Rounded corner box style."""
@staticmethod
def Square(pad=0.3) -> BoxStyle:
"""Square corner box style."""
@staticmethod
def Sawtooth(pad=0.3, tooth_size=None) -> BoxStyle:
"""Sawtooth edge box style."""
@staticmethod
def Circle(pad=0.3) -> BoxStyle:
"""Circular box style."""
class ArrowStyle:
"""Arrow styling options for FancyArrowPatch."""
@staticmethod
def Simple(head_length=0.5, head_width=0.5, tail_width=0.2) -> ArrowStyle:
"""Simple arrow style."""
@staticmethod
def Fancy(head_length=0.4, head_width=0.4, tail_width=0.4) -> ArrowStyle:
"""Fancy arrow style."""
@staticmethod
def Wedge(tail_width=0.3, shrink_factor=0.5) -> ArrowStyle:
"""Wedge arrow style."""
class ConnectionStyle:
"""Connection styling options for connecting patches."""
@staticmethod
def Arc3(rad=0.0) -> ConnectionStyle:
"""Arc connection with specified radius."""
@staticmethod
def Angle3(angleA=90, angleB=0) -> ConnectionStyle:
"""Angle connection with specified angles."""
@staticmethod
def Bar(armA=0.0, armB=0.0, fraction=0.3, angle=None) -> ConnectionStyle:
"""Bar connection style."""import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import numpy as np
fig, ax = plt.subplots(figsize=(12, 8))
# Rectangle
rect = mpatches.Rectangle((0.1, 0.1), 0.3, 0.2,
facecolor='lightblue', edgecolor='blue', linewidth=2)
ax.add_patch(rect)
# Circle
circle = mpatches.Circle((0.6, 0.2), 0.1,
facecolor='lightcoral', edgecolor='red', linewidth=2)
ax.add_patch(circle)
# Ellipse
ellipse = mpatches.Ellipse((0.2, 0.6), 0.2, 0.1, angle=45,
facecolor='lightgreen', edgecolor='green', linewidth=2)
ax.add_patch(ellipse)
# Polygon (triangle)
triangle = mpatches.Polygon([(0.5, 0.5), (0.7, 0.5), (0.6, 0.7)],
facecolor='yellow', edgecolor='orange', linewidth=2)
ax.add_patch(triangle)
# Regular polygon (hexagon)
hexagon = mpatches.RegularPolygon((0.8, 0.7), 6, radius=0.08,
facecolor='plum', edgecolor='purple', linewidth=2)
ax.add_patch(hexagon)
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_aspect('equal')
ax.set_title('Basic Shapes')
ax.grid(True, alpha=0.3)
plt.show()import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
fig, ax = plt.subplots(figsize=(12, 8))
# Simple arrow
arrow1 = mpatches.Arrow(0.1, 0.1, 0.2, 0.1, width=0.05, color='red')
ax.add_patch(arrow1)
# Fancy arrow
arrow2 = mpatches.FancyArrow(0.1, 0.3, 0.3, 0.0, width=0.02, head_width=0.05,
head_length=0.03, fc='blue', ec='darkblue')
ax.add_patch(arrow2)
# Fancy arrow patch with custom styling
arrow3 = mpatches.FancyArrowPatch((0.1, 0.5), (0.4, 0.7),
arrowstyle='->', mutation_scale=20,
color='green', linewidth=2)
ax.add_patch(arrow3)
# Curved arrow
arrow4 = mpatches.FancyArrowPatch((0.6, 0.2), (0.8, 0.6),
connectionstyle='arc3,rad=0.3',
arrowstyle='-|>', mutation_scale=20,
color='purple', linewidth=2)
ax.add_patch(arrow4)
# Bidirectional arrow
arrow5 = mpatches.FancyArrowPatch((0.5, 0.8), (0.9, 0.8),
arrowstyle='<->', mutation_scale=20,
color='orange', linewidth=2)
ax.add_patch(arrow5)
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_aspect('equal')
ax.set_title('Arrow Examples')
ax.grid(True, alpha=0.3)
plt.show()import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
fig, ax = plt.subplots(figsize=(12, 8))
# Fancy bounding boxes with different styles
styles = ['round', 'square', 'sawtooth', 'circle']
colors = ['lightblue', 'lightcoral', 'lightgreen', 'lightyellow']
for i, (style, color) in enumerate(zip(styles, colors)):
x = 0.1 + (i % 2) * 0.4
y = 0.6 - (i // 2) * 0.3
bbox = mpatches.FancyBboxPatch((x, y), 0.25, 0.15,
boxstyle=f"{style},pad=0.02",
facecolor=color, edgecolor='black',
linewidth=1.5)
ax.add_patch(bbox)
# Add text label
ax.text(x + 0.125, y + 0.075, style.capitalize(),
ha='center', va='center', fontsize=12, weight='bold')
# Wedge (pie slice)
wedge = mpatches.Wedge((0.8, 0.3), 0.15, 30, 120,
facecolor='gold', edgecolor='orange', linewidth=2)
ax.add_patch(wedge)
# Arc
arc = mpatches.Arc((0.8, 0.3), 0.3, 0.3, angle=0, theta1=150, theta2=390,
edgecolor='red', linewidth=3)
ax.add_patch(arc)
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_aspect('equal')
ax.set_title('Advanced Patch Styling')
ax.grid(True, alpha=0.3)
plt.show()import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import numpy as np
def create_flowchart():
"""Create a simple flowchart using patches."""
fig, ax = plt.subplots(figsize=(12, 10))
# Define positions and sizes
boxes = [
{'xy': (0.2, 0.8), 'size': (0.15, 0.08), 'text': 'Start', 'style': 'round'},
{'xy': (0.2, 0.6), 'size': (0.15, 0.08), 'text': 'Process', 'style': 'square'},
{'xy': (0.2, 0.4), 'size': (0.15, 0.08), 'text': 'Decision', 'style': 'round'},
{'xy': (0.5, 0.4), 'size': (0.15, 0.08), 'text': 'Yes Branch', 'style': 'square'},
{'xy': (0.2, 0.2), 'size': (0.15, 0.08), 'text': 'No Branch', 'style': 'square'},
{'xy': (0.5, 0.2), 'size': (0.15, 0.08), 'text': 'End', 'style': 'round'}
]
# Create boxes
for box in boxes:
patch = mpatches.FancyBboxPatch(
box['xy'], box['size'][0], box['size'][1],
boxstyle=f"{box['style']},pad=0.01",
facecolor='lightblue', edgecolor='navy', linewidth=2
)
ax.add_patch(patch)
# Add text
center_x = box['xy'][0] + box['size'][0]/2
center_y = box['xy'][1] + box['size'][1]/2
ax.text(center_x, center_y, box['text'],
ha='center', va='center', fontsize=10, weight='bold')
# Add connecting arrows
arrows = [
((0.275, 0.8), (0.275, 0.68)), # Start to Process
((0.275, 0.6), (0.275, 0.48)), # Process to Decision
((0.35, 0.44), (0.5, 0.44)), # Decision to Yes
((0.275, 0.4), (0.275, 0.28)), # Decision to No
((0.575, 0.4), (0.575, 0.28)) # Yes to End
]
for start, end in arrows:
arrow = mpatches.FancyArrowPatch(start, end,
arrowstyle='->', mutation_scale=15,
color='darkblue', linewidth=2)
ax.add_patch(arrow)
# Add labels for decision branches
ax.text(0.42, 0.46, 'Yes', ha='center', va='center', fontsize=9,
bbox=dict(boxstyle='round,pad=0.3', facecolor='white', alpha=0.8))
ax.text(0.3, 0.32, 'No', ha='center', va='center', fontsize=9,
bbox=dict(boxstyle='round,pad=0.3', facecolor='white', alpha=0.8))
ax.set_xlim(0, 0.8)
ax.set_ylim(0, 1)
ax.set_aspect('equal')
ax.set_title('Flowchart Example using Patches')
ax.axis('off')
plt.show()
create_flowchart()import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.path import Path
import numpy as np
# Create custom star shape using Path
def create_star(center, radius, n_points=5):
"""Create a star shape path."""
angles = np.linspace(0, 2*np.pi, n_points*2, endpoint=False)
radii = np.array([radius, radius*0.4] * n_points)
x = center[0] + radii * np.cos(angles)
y = center[1] + radii * np.sin(angles)
vertices = list(zip(x, y))
codes = [Path.MOVETO] + [Path.LINETO] * (len(vertices)-2) + [Path.CLOSEPOLY]
return Path(vertices, codes)
fig, ax = plt.subplots(figsize=(10, 8))
# Create multiple custom stars
centers = [(0.2, 0.3), (0.5, 0.7), (0.8, 0.4)]
radii = [0.08, 0.12, 0.06]
colors = ['gold', 'orange', 'yellow']
for center, radius, color in zip(centers, radii, colors):
star_path = create_star(center, radius)
star_patch = mpatches.PathPatch(star_path, facecolor=color,
edgecolor='darkorange', linewidth=2)
ax.add_patch(star_patch)
# Add some decorative circles
for i in range(8):
angle = i * np.pi / 4
x = 0.5 + 0.3 * np.cos(angle)
y = 0.5 + 0.3 * np.sin(angle)
circle = mpatches.Circle((x, y), 0.02, facecolor='lightblue',
edgecolor='blue', alpha=0.7)
ax.add_patch(circle)
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_aspect('equal')
ax.set_title('Custom Shapes with Paths')
ax.set_facecolor('lightgray')
ax.grid(True, alpha=0.3)
plt.show()Install with Tessl CLI
npx tessl i tessl/pypi-matplotlib