This is a minimal header-only and dependency-free C++ plotting library.
It's maintained mostly for internal Signalsmith Audio use, so I'm adding features as I need them.
- SVG output only
- auto-styled lines and fills
- simultaneous colour/dash/hatch/marker sequences for accessibility
- styling done via (customisable) CSS where possible
- custom JS (included as source or URL)
- explicit labelling on lines, or legends
- values labelled with three levels: major/minor/tick
- no explicit axis-lines, use major gridlines instead
- simplifies paths
- attempts not to draw out-of-view data
- drops points along almost-straight lines
- each plot's edge can have multiple partial axes
- basic grid (each row/column stretches to contain its contents)
- animated graphs with
<animate>(SMIL)
- only 2D plots supported
- no automatic label placement or de-collision
- text lengths are heuristically estimated
All you need is the header file:
#include "plot.h";View the API docs for complete info.
Here's a minimal example, which sets up a 2D plot, adds some grid-lines/ticks:
// Set up a plot
signalsmith::plot::Plot2D plot;
// Place the grid/ticks
plot.x.majors(0, 10).tick(5).minor(3.5);
ploy.y.major(0);
// If you don't set the scale, it will guess from data/ticks
plot.x.linear(0, 15);
// You can use custom scales, using any function
// (or lambda) which accepts/returns `double`
plot.y.range(std::log, 1, 1000);
// Set up a line
auto &line = plot.line();
for (auto &p : points) {
// Add points as x/y pairs
line.add(p.x, p.y);
}
// or from array (using `.size()` if not specified)
line.addArray(xArr, yArr);
plot.write("example.svg");See examples.cpp for code examples. Here are the images generated by that code:
You create a top-level object, which could be a Figure or a Plot2D:
signalsmith::plot::Plot2D plot;When you create a sub-object (line, sub-plot, etc.), you are returned a reference. These elements are deliberately not copyable, so if you use auto instead of auto & it will complain.
auto &line = plot.line();Many methods return a reference to the object, allowing you to chain them together, e.g.:
plot.x.major(0, 10).minor(5);There's an additional module in heatmap.h for pixel-based heat-maps:
This uses the PlotStyle's cmap to generate 256 RGB(A) colour-map values, then outputs an indexed PNG.
You can customise the styles using PlotStyle objects. For individual Figures you can use the .style field, or for all plots you can alter PlotStyle::defaultStyle().
Additionally, if there is a "signalsmith-plot-style.h" in the include path, this is automatically #included by plot.h. You can use this to define a custom style per-project or system-wide. Since the library is header-only, the best way to customise is the constructor of a static global variable:
static struct MyCustomStyle {
MyCustomStyle() {
auto &style = signalsmith::plot::PlotStyle::defaultStyle();
// ... get funky
}
} myCustomStyle;There aren't any unit tests, just a visual check of the example plots.
Released as 0BSD. If you need anything else, get in touch. 🙂