Skip to content

Commit 3f5b276

Browse files
committed
matplotlib.h: add support for contiguous_range (C++20) and ranges.cpp example
1 parent 6255877 commit 3f5b276

File tree

3 files changed

+362
-53
lines changed

3 files changed

+362
-53
lines changed

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ if(Python3_NumPy_FOUND)
104104
target_link_libraries(span PRIVATE matplotlib_cpp)
105105
target_compile_features(span PRIVATE cxx_std_20)
106106
set_target_properties(span PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
107+
108+
add_executable(ranges examples/ranges.cpp)
109+
target_link_libraries(ranges PRIVATE matplotlib_cpp)
110+
target_compile_features(ranges PRIVATE cxx_std_20)
111+
set_target_properties(ranges PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
112+
107113
endif()
108114

109115

examples/ranges.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
//
2+
// g++ -std=c++20 -g -Wall -o ranges $(python-config --includes) ranges.cpp $(python-config --ldflags --embed)
3+
//
4+
// g++ -std=c++17 -g -Wall -o ranges $(python-config --includes) ranges.cpp $(python-config --ldflags --embed)
5+
//
6+
#include "../matplotlibcpp.h"
7+
8+
#include <iostream>
9+
#include <list>
10+
#include <map>
11+
#include <span>
12+
#include <string>
13+
#include <vector>
14+
15+
#define UNUSED(x) (void)(x)
16+
17+
using namespace std;
18+
namespace plt = matplotlibcpp;
19+
20+
int main()
21+
{
22+
plt::detail::_interpreter::get();
23+
24+
25+
#if __cplusplus >= CPP20
26+
27+
// C-style arrays with multiple rows.
28+
29+
// Care with column-major vs row-major!
30+
// C and Python are row-major, but usually a time series is column-major
31+
// and we want to plot the columns.
32+
// In the example below, these columns are [3,1,4,5] and [5,4,1,3], so
33+
// the data must be stored like this:
34+
time_t t[]={1, 2, 3, 4};
35+
double data [] = {
36+
3, 5,
37+
1, 4,
38+
4, 1,
39+
5, 3
40+
};
41+
42+
// Use std::span() to convert to a contiguous range (O(1)).
43+
// Data won't be copied, but passed as a pointer to Python.
44+
plt::plot(span(t, 4), span(data, 8));
45+
plt::grid(true);
46+
plt::title("C-arrays, with multiple columns");
47+
plt::show();
48+
49+
#else
50+
51+
cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << ": "
52+
<< "No support for contiguous ranges." << endl;
53+
54+
#endif
55+
56+
// vectors
57+
58+
// Vectors are also contiguous ranges.
59+
// In C++20, as with span, plot resolves to plot(contiguous_range).
60+
// In C++ < 20 plot resolves to plot(vector).
61+
vector<double> x={1, 2, 3, 4, 5};
62+
vector<double> y={0, 1, 0, -1, 0};
63+
plt::plot(x, y);
64+
plt::grid(true);
65+
plt::title("vectors");
66+
plt::show();
67+
68+
69+
// lists
70+
71+
// By contrast, lists are non-contiguous (but iterable) containers, so
72+
// plot resolves to plot(iterable).
73+
list<double> u { 1, 2, 3, 4, 5};
74+
list<double> v { 0, -1, 0, 1, 0};
75+
plt::plot(u, v, "");
76+
plt::grid(true);
77+
plt::title("Lists (non-contiguous ranges)");
78+
plt::show();
79+
80+
81+
// All together now
82+
#if __cplusplus >= CPP20
83+
84+
// If span is not last, plot resolves to plot(iterable), which copies data.
85+
// That's because in the dispatch plot() we have plot_impl() && plot()
86+
// (i.e. plot_impl() comes first), and we only have iterable and
87+
// callable plot_impl(). That sends us to the iterable plot_impl(),
88+
// rather than to plot(contiguous_range).
89+
//
90+
// TODO: have 3 tags plot_impl(): iterable, callable and contiguous range.
91+
plt::plot(span(t, 4), span(data, 8), "", x, y, "b", u, v, "r");
92+
93+
// This resolves to plot(contiguous_range) and does not copy data.
94+
// plt::plot(x, y, "b", u, v, "r", span(t, 4), span(data, 8));
95+
#else
96+
plt::plot(x, y, "b", u, v, "r");
97+
#endif
98+
plt::grid(true);
99+
plt::title("Variadic templates recursion");
100+
plt::show();
101+
102+
plt::detail::_interpreter::kill();
103+
104+
return 0;
105+
}

0 commit comments

Comments
 (0)