matplotlib/matplotlib

matplotlib: plotting with Python

22,723 stars Python 8 components

10 hidden assumptions · 6-stage pipeline · 8 components

Like any codebase, this library makes assumptions it never checks — most are routine. The ones worth your attention are below.

Renders publication-quality static, animated, and interactive plots across multiple output formats

User plotting commands flow through pyplot or object-oriented APIs to create Artist objects in a hierarchical scene graph. During rendering, the scene graph is traversed depth-first, with each Artist applying coordinate transformations and issuing drawing commands to a backend-specific renderer. The AGG rendering engine converts vector paths into anti-aliased pixels, which are then output to files, displays, or web interfaces through backend-specific handlers.

Under the hood, the system uses 3 feedback loops, 3 data pools, 4 control points to manage its runtime behavior.

A 8-component library. 1131 files analyzed. Data flows through 6 distinct pipeline stages.

Hidden Assumptions

Most of what this code assumes is routine. These 3 are the ones most likely to cause trouble here. The rest are minor; they're under "Show everything".

Worth your attention first

Invalid angle inputs (like extremely large values or NaN) could cause infinite loops in arc tessellation or produce garbage geometry that renders as visual artifacts

Worth your attention first

Highly curved or degenerate bezier curves could exceed recursion limit and produce incomplete or incorrect curve tessellation, causing missing plot elements

Worth your attention first

Large filter radius values could allocate gigabytes of memory for lookup tables, causing out-of-memory errors or system instability

Show everything (7 more)
Domain

Curve approximation epsilons (1e-30) are appropriate for all coordinate scales from microscopic to astronomical data

If this fails: Plots with very large coordinate values (like astronomical data) or very small values (like molecular simulations) could have curves that fail to tessellate properly or consume excessive memory

extern/agg24-svn/src/agg_curves.cpp:curve_distance_epsilon
Shape

B-spline control point arrays (m_x, m_y) remain valid pointers throughout the spline's lifetime

If this fails: If the arrays passed to bspline are deallocated or reallocated elsewhere, the spline object accesses freed memory causing crashes or corruption

extern/agg24-svn/src/agg_bspline.cpp:bspline
Domain

Line width values are in the same coordinate system as the smoothing width and both represent pixel-based measurements

If this fails: Mixing coordinate systems (data coordinates vs pixel coordinates) in line width calculations produces lines that are either invisibly thin or massively thick

extern/agg24-svn/src/agg_line_profile_aa.cpp:width
Ordering

Rectangle coordinates x1,y1 represent bottom-left and x2,y2 represent top-right, with automatic coordinate swapping handling all cases

If this fails: Code that depends on specific corner semantics after construction could access wrong corners, leading to incorrect clipping or rendering bounds

extern/agg24-svn/src/agg_rounded_rect.cpp:rect
Domain

The embedded GSV font data has a specific binary format with fixed header structure and glyph encoding

If this fails: If font data gets corrupted or the format assumptions change, text rendering fails silently or produces garbage characters

extern/agg24-svn/src/agg_gsv_text.cpp:gsv_default_font
Scale

Arrowhead dimensions (m_head_d1, m_head_d2, etc.) are in the same units as the path coordinates they will be applied to

If this fails: Unit mismatches cause arrows that are either invisible (too small) or dominate the plot (too large), making line plots unreadable

extern/agg24-svn/src/agg_arrowhead.cpp:arrowhead
Resource

Embedded font bitmap data fits in available memory and character codes map correctly to glyph indices

If this fails: Invalid character codes or corrupted bitmap data causes buffer overruns or displays wrong characters in plot labels and titles

extern/agg24-svn/src/agg_embedded_raster_fonts.cpp:gse4x6

Open the standalone hidden-assumptions report for matplotlib →

How Data Flows Through the System

User plotting commands flow through pyplot or object-oriented APIs to create Artist objects in a hierarchical scene graph. During rendering, the scene graph is traversed depth-first, with each Artist applying coordinate transformations and issuing drawing commands to a backend-specific renderer. The AGG rendering engine converts vector paths into anti-aliased pixels, which are then output to files, displays, or web interfaces through backend-specific handlers.

  1. Parse plotting command — pyplot functions like plot() or scatter() parse user arguments for data arrays, style parameters, and keyword options, validating data types and handling missing values [User plotting commands → Plot data arrays]
  2. Create Artist hierarchy — Axes methods like _plot_helper create Line2D, Patch, or Collection objects with visual properties from rcParams defaults and user overrides, building parent-child relationships [Plot data arrays → Artist]
  3. Transform coordinates — Each Artist applies its transform chain to convert from data coordinates through Axes coordinates to Figure coordinates and finally display pixels using affine transformation matrices [Artist → Transform]
  4. Generate geometry paths — Artists convert their data into Path objects containing vertices and drawing codes (MOVETO, LINETO, CURVE) that define the geometric shapes to be rendered [Transform → Path]
  5. Rasterize with AGG — The AGG renderer processes Path objects through scanline rasterization, applying anti-aliasing, alpha blending, and clipping to generate RGBA pixel arrays [Path → Pixel arrays]
  6. Output to backend — Backend-specific code takes pixel arrays and metadata to generate final output: writing PNG/PDF files, updating GUI windows, or creating web-displayable formats [Pixel arrays → Rendered output]

Data Models

The data structures that flow between stages — the contracts that hold the system together.

Artist lib/matplotlib/artist.py
Base class with properties dict containing visual attributes (color, linewidth, alpha, transform), plus draw() method that renders to a renderer
Created by plotting functions, assembled into hierarchical scene graph, then rendered by backend-specific renderer during figure drawing
Transform lib/matplotlib/transforms.py
Affine transformation matrix with methods for coordinate conversion between data space, Axes space, Figure space, and display space
Built during axes creation to map data coordinates to pixel coordinates, updated when axes limits change, applied during Artist rendering
Path lib/matplotlib/path.py
Vertices array of (x,y) coordinates plus codes array defining line segments, curves, and closures using MOVETO, LINETO, CURVE3, CURVE4, CLOSEPOLY commands
Generated from plot data (lines, polygons, text outlines), processed through clipping and transformation pipeline, then rasterized by AGG engine
Renderer lib/matplotlib/backend_bases.py
Abstract base with methods for drawing primitives (draw_path, draw_text, draw_image) and properties for DPI, size, and output format capabilities
Instantiated by backend during figure creation, receives drawing commands from Artists, translates to backend-specific graphics operations
RcParams lib/matplotlib/rcsetup.py
Dict-like configuration registry with parameter names as keys, values validated by type-specific functions, organized into categories like figure, axes, font, lines
Loaded from matplotlibrc files and environment variables at startup, accessed by Artists to set default visual properties, modified by user preference functions

System Behavior

How the system operates at runtime — where data accumulates, what loops, what waits, and what controls what.

Data Pools

rcParams registry (registry)
Global configuration dictionary storing default values for visual properties like figure size, font family, line width, and color schemes
Font cache (cache)
Cached mapping of font family names to font file paths, populated by scanning system font directories and updated when new fonts are installed
Figure manager registry (registry)
Tracks all active Figure objects and their associated GUI windows for proper cleanup and event handling in interactive backends

Feedback Loops

Delays

Control Points

Technology Stack

Anti-Grain Geometry (AGG) (compute)
High-performance C++ 2D graphics library that provides sub-pixel precision rasterization, anti-aliasing, and alpha blending for matplotlib's core rendering engine
NumPy (library)
Fundamental array library that matplotlib builds on for efficient storage and manipulation of plot data, coordinate arrays, and pixel buffers
FreeType (library)
Font rendering engine used through the AGG integration to rasterize text with proper glyph metrics, kerning, and sub-pixel positioning
Pillow (library)
Image processing library used for loading, manipulating, and saving raster image formats in matplotlib's image handling pipeline
Cycler (library)
Property cycling utility that automatically varies colors, line styles, and markers when plotting multiple data series
Pyparsing (library)
Text parsing library used for mathematical expressions in LaTeX rendering and font configuration file parsing
Kiwi Solver (library)
Constraint solver used in matplotlib's layout engine for automatic subplot positioning and tight_layout functionality
Meson (build)
Modern build system that compiles C++ extensions, manages dependencies, and handles cross-platform compilation of the AGG rendering engine

Key Components

Explore the interactive analysis

See the full architecture map, data flow, and code patterns visualization.

Analyze on CodeSea

Related Library Repositories

Frequently Asked Questions

What is matplotlib used for?

Renders publication-quality static, animated, and interactive plots across multiple output formats matplotlib/matplotlib is a 8-component library written in Python. Data flows through 6 distinct pipeline stages. The codebase contains 1131 files.

How is matplotlib architected?

matplotlib is organized into 4 architecture layers: User Interface Layer, Artist Layer, Backend Layer, Rendering Engine. Data flows through 6 distinct pipeline stages. This layered structure keeps concerns separated and modules independent.

How does data flow through matplotlib?

Data moves through 6 stages: Parse plotting command → Create Artist hierarchy → Transform coordinates → Generate geometry paths → Rasterize with AGG → .... User plotting commands flow through pyplot or object-oriented APIs to create Artist objects in a hierarchical scene graph. During rendering, the scene graph is traversed depth-first, with each Artist applying coordinate transformations and issuing drawing commands to a backend-specific renderer. The AGG rendering engine converts vector paths into anti-aliased pixels, which are then output to files, displays, or web interfaces through backend-specific handlers. This pipeline design reflects a complex multi-stage processing system.

What technologies does matplotlib use?

The core stack includes Anti-Grain Geometry (AGG) (High-performance C++ 2D graphics library that provides sub-pixel precision rasterization, anti-aliasing, and alpha blending for matplotlib's core rendering engine), NumPy (Fundamental array library that matplotlib builds on for efficient storage and manipulation of plot data, coordinate arrays, and pixel buffers), FreeType (Font rendering engine used through the AGG integration to rasterize text with proper glyph metrics, kerning, and sub-pixel positioning), Pillow (Image processing library used for loading, manipulating, and saving raster image formats in matplotlib's image handling pipeline), Cycler (Property cycling utility that automatically varies colors, line styles, and markers when plotting multiple data series), Pyparsing (Text parsing library used for mathematical expressions in LaTeX rendering and font configuration file parsing), and 2 more. A focused set of dependencies that keeps the build manageable.

What system dynamics does matplotlib have?

matplotlib exhibits 3 data pools (rcParams registry, Font cache), 3 feedback loops, 4 control points, 3 delays. The feedback loops handle polling and convergence. These runtime behaviors shape how the system responds to load, failures, and configuration changes.

What design patterns does matplotlib use?

4 design patterns detected: Artist Hierarchy, Backend Abstraction, Transform Pipeline, Configuration Registry.

Analyzed on April 20, 2026 by CodeSea. Written by .