Architecture
PlotSmith follows a strict 4-layer architecture with clear boundaries between layers. This design ensures separation of concerns, testability, and maintainability.
Layer 1: Data and Representations
Location: plotsmith.objects
This layer defines immutable dataclasses that represent plot-ready data and plot specifications. No matplotlib imports are allowed in this layer.
View Objects:
plotsmith.objects.SeriesView- Time series dataplotsmith.objects.BandView- Confidence bandsplotsmith.objects.ScatterView- Scatter plot dataplotsmith.objects.HistogramView- Histogram dataplotsmith.objects.BarView- Bar chart dataplotsmith.objects.HeatmapView- Heatmap dataplotsmith.objects.FigureSpec- Figure specifications
Validators: plotsmith.objects.validate contains validation functions that check shapes and alignment of view objects.
Layer 2: Primitives
Location: plotsmith.primitives
This layer defines the drawing API. It can import matplotlib and must accept only Layer 1 objects. All matplotlib calls are encapsulated here.
Drawing Functions:
plotsmith.primitives.draw_series()- Draw time seriesplotsmith.primitives.draw_band()- Draw confidence bandsplotsmith.primitives.draw_scatter()- Draw scatter plotsplotsmith.primitives.draw_histogram()- Draw histogramsplotsmith.primitives.draw_bar()- Draw bar chartsplotsmith.primitives.draw_heatmap()- Draw heatmaps
Styling Helpers:
plotsmith.primitives.minimal_axes()- Apply minimalist axes stylingplotsmith.primitives.tidy_axes()- Tidy axes stylingplotsmith.primitives.style_line_plot()- Style line plotsplotsmith.primitives.style_scatter_plot()- Style scatter plotsplotsmith.primitives.style_bar_plot()- Style bar plots
Labeling Helpers:
plotsmith.primitives.direct_label()- Add direct labelsplotsmith.primitives.note()- Add notesplotsmith.primitives.emphasize_last()- Emphasize last pointplotsmith.primitives.accent_point()- Highlight specific pointsplotsmith.primitives.event_line()- Mark events with lines
Layer 3: Tasks
Location: plotsmith.tasks
Tasks translate user intent into Layer 1 objects and a FigureSpec. Tasks can import pandas and numpy, but not matplotlib. Tasks can only import Layer 1 objects.
Task Classes:
plotsmith.tasks.TimeseriesPlotTask- Convert time series data to viewsplotsmith.tasks.BacktestPlotTask- Convert backtest results to viewsplotsmith.tasks.HistogramPlotTask- Convert data to histogram viewsplotsmith.tasks.BarPlotTask- Convert data to bar viewsplotsmith.tasks.HeatmapPlotTask- Convert data to heatmap viewsplotsmith.tasks.ResidualsPlotTask- Convert residuals to views
Layer 4: Workflows
Location: plotsmith.workflows
Workflows provide one-call entry points for users. Workflows can import matplotlib. They call tasks, then primitives, then save or show plots.
Workflow Functions:
plotsmith.workflows.plot_timeseries()- Plot time seriesplotsmith.workflows.plot_backtest()- Plot backtest resultsplotsmith.workflows.plot_residuals()- Plot residualsplotsmith.workflows.plot_histogram()- Plot histogramsplotsmith.workflows.plot_bar()- Plot bar chartsplotsmith.workflows.plot_heatmap()- Plot heatmapsplotsmith.workflows.plot_model_comparison()- Compare modelsplotsmith.workflows.figure()- Create styled figureplotsmith.workflows.small_multiples()- Create small multiples
Public API
The public API is defined in plotsmith/__init__.py and exports only:
Workflow functions
View objects (for type hints)
Styling helpers
All other modules are internal and should not be imported directly.