Header-only library code to visualize C++ numerical simulations using modern OpenGL.
Mathplot is a library for drawing 3D data visualization objects called VisualModels
.
mathplot can also be integrated with other GUI frameworks including Qt (see examples/qt/), wxWidgets (see examples/wx/) and Dear ImGui (see this ImGui example). Dear ImGui is the easiest way to add GUI control to your visualizations.
Mathplot is compatible with Linux (including Raspberry Pi), Mac OS and Windows.
You'll find all of the library code in the mplot directory and you can find example code and screenshots here. There is also a template project that uses mathplot to help you incorporate the library into your own work.
mathplot has a documentation and reference website at https://sebsjames.github.io/mathplot/.
This quick start shows dependency installation for Linux, because on this platform, it's a single call to apt (or your favourite package manager). If you're using a Mac, see README.build.mac for help getting dependencies in place. It's README.build.windows for Windows users. For notes on supported compilers, see README.build.compiler
# Install dependencies for building graph1.cpp and (almost) all the other examples (assuming Debian-like OS)
sudo apt install build-essential cmake git wget \
nlohmann-json3-dev librapidxml-dev \
freeglut3-dev libglu1-mesa-dev libxmu-dev libxi-dev \
libglfw3-dev libfreetype-dev libarmadillo-dev libhdf5-dev
git clone --recurse-submodules git@github.com:sebsjames/mathplot # Get your copy of the morphologica code
cd mathplot
mkdir build # Create a build directory
cd build
cmake .. # Call cmake to generate the makefiles
make graph1 # Compile a single one of the examples. Add VERBOSE=1 to see the compiler commands.
./examples/graph1 # Run the program. You should see a graph of a cubic function.
# After closing the graph1 program, open its source code and modify something (see examples/graph2.cpp for ideas)
gedit ../examples/graph1.cpp
The program graph1.cpp is:
// Visualize a graph. Minimal example showing how a default graph appears
#include <sm/vvec> // vvec is part of Seb's maths library
#include <mplot/Visual.h>
#include <mplot/GraphVisual.h>
int main()
{
// Set up your mplot::Visual 'scene environment'.
mplot::Visual v(1024, 768, "Made with mplot::GraphVisual");
// Create a new GraphVisual object with offset within the scene of 0,0,0
auto gv = std::make_unique<mplot::GraphVisual<double>> (sm::vec<float>({0,0,0}));
// Boilerplate bindmodel function call - do this for every model you add to a Visual
v.bindmodel (gv);
// Data for the x axis. sm::vvec is like std::vector, but with built-in maths methods
sm::vvec<double> x;
// This works like numpy's linspace() (the 3 args are "start", "end" and "num"):
x.linspace (-0.5, 0.8, 14);
// Set a graph up of y = x^3
gv->setdata (x, x.pow(3));
// finalize() makes the GraphVisual compute the vertices of the OpenGL model
gv->finalize();
// Add the GraphVisual OpenGL model to the Visual scene (which takes ownership of the unique_ptr)
v.addVisualModel (gv);
// Render the scene on the screen until user quits with 'Ctrl-q'
v.keepOpen();
return 0;
}
The program generates a clean looking graph...
...and the code is only a few lines longer than an equivalent Python program, graph1.py:
# Visualize the graph from graph1.cpp in Python
import matplotlib.pyplot as plt
import numpy as np
# Create some data for the x axis
x = np.linspace(-0.5, 0.8, 14)
# Set a graph up of y = x^3
plt.plot(x, np.power(x,3), '-o')
# Add labels
plt.title('Made with Python/numpy/matplotlib')
plt.xlabel('x')
plt.ylabel('y')
# Render the graph on the screen until user quits with 'q'
plt.show()
This header-only C++ code provides dynamic runtime visualization for your programs. It was developed to visualize simulations of dynamical systems and agent-based models in real-time.
A modern OpenGL visualization scheme called mplot::Visual provides the ability to visualise 2D and 3D graphs of surfaces, lines, bars, scatter plots and quiver plots with minimal processing overhead. Here's a mplot::Visual helloworld and a more complete example. It's almost as easy to draw a graph in C++ with mathplot as it is to do so in Python.
See the reference documentation website for a guide to the main classes.
mathplot code is enclosed in the mplot namespace. If the reference site doesn't cover it, then the header files (They're all in mplot/) contain code documentation.
You can find example programs which are compiled when you do the standard cmake-driven build of mathplot in both the tests/ subdirectory and the examples/ subdirectory.
There is also a template repository that demonstrates how you can create a project that uses mathplot: sebsjames/mathplot_template.
For more info on how to set up CMake files to build a program using mathplot (and some hints as to what you'll need to do with an alternative directed build system), see README.cmake.md.
Authorship of mathplot code is given in each file. Copyright in the software is owned by the authors. Refer to morphologica for historical code authorship details (some of the code distributed here was written by contributors to morphologica). The original idea to use OpenGL to graph hexagonal grids came from Stuart Wilson. Seb James reimplemented Stuart's hexgrid plotting code in modern OpenGL and developed morphologica into a general purpose visualization library. In 2025, Seb changed the name to mathplot to indicate to new developers what functionality the library provides.
mathplot is made possible by a number of third party projects whose source code is included in this repository. These include lodepng, rapidxml, incbin, UniformBicone, jcvoronoi and the HEALPix implementation from Astrometry.net. Thanks to the authors of these projects!
mathplot is distributed under the terms of the Apache License, version 2 (see LICENSE.txt).