Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

template to handle strings on x axis w/ legend#254

Open
im-hashim wants to merge 3 commits into
lava:master from
im-hashim:patch-1
Open

template to handle strings on x axis w/ legend #254
im-hashim wants to merge 3 commits into
lava:master from
im-hashim:patch-1

Conversation

@im-hashim

@im-hashim im-hashim commented Mar 2, 2021

Copy link
Copy Markdown

bool named_plot(const std::string& name, const std::vectorstd::string& 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.

bool named_plot(const std::string& name, const std::vector<std::string>& x, const std::vector<Numeric>& 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.

lava commented Apr 2, 2021

Copy link
Copy Markdown
Owner

Thanks for contributing!

I'm a bit confused if/why this works, it's not mentioned on the matplotlib docs that x can be a vector of strings: https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.plot.html

Would you mind adding an example that uses this function, so I can check out that this works as it should?

im-hashim reacted with thumbs up emoji

im-hashim commented Apr 3, 2021 via email

Copy link
Copy Markdown
Author
Hi, This is needed as Python can handle string conversions easily for some users.. But to look forward to similar functionality in CPP, we sometimes need texts / name plots or here in my case I wanted to have time in "<Month>< >Year" format on the X-Axis. I used it to represent peak speed reached per month for a vehicle using: plot::named_plot("Vehicle speed (max)", mon_yy, veh_spd); // where mon_yy and veh_spd are vectors of which mon_yy is a mix of string and numbers. The resultant looks similar to this: [image: image.png] The current implementation will not accept spaces or characters as vectors. Hence just prototyped a simple template for strings. I hope this helps! Thank you!
...
On Fri, Apr 2, 2021 at 4:40 PM Benno Evers ***@***.***> wrote: Thanks for contributing! I'm a bit confused if/why this works, it's not mentioned on the matplotlib docs that x can be a vector of strings: https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.plot.html Would you mind adding an example that uses this function, so I can check out that this works as it should? — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub <#254 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AKKMLTO5PKJBV7RQV6QFXY3TGYTS7ANCNFSM4YPAYPNQ> .

Copy link
Copy Markdown
Author

@lava this is open for more than 2 years. if my response answers your question, can you please merge my pull request ?

Copilot AI review requested due to automatic review settings April 16, 2026 17:43

Copy link
Copy Markdown
Author

Thanks for the review and for asking for a concrete example.

I added a small runnable example at:

  • examples/string_xaxis_named_plot.cpp

I also added a short README usage note and constraints under the examples section.

Expected behavior:

  • named_plot("Vehicle speed (max)", x, y, "o-") works with x as std::vector<std::string> and numeric y of matching length.
  • Matplotlib treats the string labels as categorical x-axis values.
  • Calling legend() shows the provided series label.
  • The example saves string_xaxis_named_plot.png (and can be switched to show() for interactive runs).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an API/example intended to support named_plot() with std::vector<std::string> x-axis values so users can plot categorical/string x-values while still using legend labels.

Changes:

  • Introduces a new named_plot overload for x: std::vector<std::string> in matplotlibcpp.h.
  • Adds a new example demonstrating string x-axis + legend plotting.
  • Documents the new example/usage in the README.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
matplotlibcpp.h Adds a named_plot overload for string x-values (and accidentally adds a broken named_semilogx declaration).
examples/string_xaxis_named_plot.cpp New runnable example plotting categorical month labels with a legend and saving an image.
README.md Adds documentation snippet and build command for the new example.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.md
Comment on lines +68 to +92
String x-axis labels with legend:
```cpp
#include "../matplotlibcpp.h"
#include <string>
#include <vector>

namespace plt = matplotlibcpp;

int main()
{
std::vector<std::string> x = {"Jan 2021", "Feb 2021", "Mar 2021"};
std::vector<double> 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<std::string>` 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.

Copilot AI Apr 16, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description/README section implies legends (and/or string x-axis support) are newly enabled, but the library already provides named_plot(...) for legend labels and detail::get_array(std::vector<std::string>) for string data. Consider updating the README text to clarify what limitation is actually being addressed (e.g., providing a dedicated overload), or remove the claim that this capability was previously unavailable.

Copilot uses AI. Check for mistakes.
Comment thread matplotlibcpp.h
Comment on lines +1756 to +1758
template<typename Numeric>
bool named_semilogx(const std::string& name, const std::vector<Numeric>& x, const std::vector<Numeric>& y, const std::string& format = "")

Copilot AI Apr 16, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an incomplete named_semilogx template declaration here (no function body and no trailing ;). This will not compile and also duplicates the existing named_semilogx template immediately below—remove this line or provide a proper definition/forward declaration ending with ;.

Suggested change
template<typename Numeric>
bool named_semilogx(const std::string& name, const std::vector<Numeric>& x, const std::vector<Numeric>& y, const std::string& format = "")

Copilot uses AI. Check for mistakes.
Comment thread matplotlibcpp.h
Comment on lines +1734 to +1736
PyObject* kwargs = PyDict_New();
PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str()));

Copilot AI Apr 16, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PyDict_SetItemString does not steal a reference to the value; passing the temporary result of PyString_FromString(...) here leaks a reference. Store the created Python string in a local PyObject*, insert it into kwargs, then Py_DECREF it after insertion (same pattern as used elsewhere when the API doesn’t steal refs).

Copilot uses AI. Check for mistakes.
Comment thread matplotlibcpp.h
Comment on lines +1730 to +1756
bool named_plot(const std::string& name, const std::vector<std::string>& x, const std::vector<Numeric>& 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<typename Numeric>

Copilot AI Apr 16, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This overload appears redundant: the existing named_plot template taking std::vector<NumericX> already works with NumericX = std::string because detail::get_array(const std::vector<std::string>&) is defined. Keeping both copies increases maintenance surface; consider removing this overload and relying on the generic template (or factoring shared logic into a helper).

Suggested change
bool named_plot(const std::string& name, const std::vector<std::string>& x, const std::vector<Numeric>& 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<typename Numeric>

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Author

Hi @lava, I added the requested runnable example and README note in commit 9eb18b0. Could you please merge if this looks good?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

Copilot code review Copilot Copilot left review comments

+1 more reviewer

@hashimabdul hashimabdul hashimabdul approved these changes

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /