From 84148ab721450a45c0e390409d2c5fbe4e6cb071 Mon Sep 17 00:00:00 2001 From: Hashim Abdul Date: Tue, 2 Mar 2021 08:53:42 -0500 Subject: [PATCH 1/2] template to handle strings on x axis w/ legend bool named_plot(const std::string& name, const std::vector& x, const std::vector& y, const std::string& format = "") { .. } added template to be able to have named legend plotting: ex: time(x) vs signal(y) with legend. Prior to this change, the current library implements simple plots with no legends and with this change the above should be possible. --- matplotlibcpp.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/matplotlibcpp.h b/matplotlibcpp.h index 93a72be5..f8858c9a 100644 --- a/matplotlibcpp.h +++ b/matplotlibcpp.h @@ -1394,6 +1394,33 @@ bool named_plot(const std::string& name, const std::vector& x, const st return res; } +template +bool named_plot(const std::string& name, const std::vector& x, const std::vector& y, const std::string& format = "") +{ + detail::_interpreter::get(); + + PyObject* kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); + + PyObject* xarray = detail::get_array(x); + PyObject* yarray = detail::get_array(y); + + PyObject* pystring = PyString_FromString(format.c_str()); + + PyObject* plot_args = PyTuple_New(3); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); + PyTuple_SetItem(plot_args, 2, pystring); + + PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_plot, plot_args, kwargs); + + Py_DECREF(kwargs); + Py_DECREF(plot_args); + if (res) Py_DECREF(res); + + return res; +} + template bool named_semilogx(const std::string& name, const std::vector& x, const std::vector& y, const std::string& format = "") { From 9eb18b069dc35249b160474b788016445676993a Mon Sep 17 00:00:00 2001 From: Hashim Abdul Date: Thu, 16 Apr 2026 13:43:16 -0400 Subject: [PATCH 2/2] Add string x-axis named_plot example and docs note --- README.md | 25 +++++++++++++++++++++++++ examples/string_xaxis_named_plot.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 examples/string_xaxis_named_plot.cpp diff --git a/README.md b/README.md index 0f8479f1..278a87dc 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,31 @@ int main() ![Basic example](./examples/basic.png) +String x-axis labels with legend: +```cpp +#include "../matplotlibcpp.h" +#include +#include + +namespace plt = matplotlibcpp; + +int main() +{ + std::vector x = {"Jan 2021", "Feb 2021", "Mar 2021"}; + std::vector y = {58.4, 61.2, 63.9}; + + plt::named_plot("Vehicle speed (max)", x, y, "o-"); + plt::legend(); + plt::save("./string_xaxis_named_plot.png"); +} +``` + g++ examples/string_xaxis_named_plot.cpp -std=c++11 -I. -I/usr/include/python2.7 -lpython2.7 + +Expected behavior and constraints: +- `x` is a `std::vector` and `y` is numeric with matching length. +- String labels are mapped as categorical x values by matplotlib. +- Use `plt::save(...)` for headless runs or `plt::show()` for interactive runs. + Alternatively, matplotlib-cpp also supports some C++11-powered syntactic sugar: ```cpp #include diff --git a/examples/string_xaxis_named_plot.cpp b/examples/string_xaxis_named_plot.cpp new file mode 100644 index 00000000..6a1d80b0 --- /dev/null +++ b/examples/string_xaxis_named_plot.cpp @@ -0,0 +1,25 @@ +#include "../matplotlibcpp.h" +#include +#include + +namespace plt = matplotlibcpp; + +int main() +{ + const std::vector months = { + "Jan 2021", "Feb 2021", "Mar 2021", "Apr 2021", "May 2021" + }; + const std::vector speed_kmh = {58.4, 61.2, 63.9, 62.1, 65.0}; + + plt::figure_size(900, 500); + plt::named_plot("Vehicle speed (max)", months, speed_kmh, "o-"); + plt::title("Monthly peak speed"); + plt::xlabel("Month"); + plt::ylabel("Speed (km/h)"); + plt::legend(); + plt::tight_layout(); + + // Use save() for CI/headless usage; replace with show() for interactive runs. + plt::save("./string_xaxis_named_plot.png"); + return 0; +}