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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy