sciplot  0.3.1
A modern C++ plotting library powered by gnuplot
Plot2D.hpp
1 // sciplot - a modern C++ scientific plotting library powered by gnuplot
2 // https://github.com/sciplot/sciplot
3 //
4 // Licensed under the MIT License <http://opensource.org/licenses/MIT>.
5 //
6 // Copyright (c) 2018-2022 Allan Leal, Bim Overbohm
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
25 
26 #pragma once
27 
28 // C++ includes
29 #include <sstream>
30 #include <vector>
31 
32 // sciplot includes
33 #include <sciplot/Constants.hpp>
34 #include <sciplot/Default.hpp>
35 #include <sciplot/Enums.hpp>
36 #include <sciplot/Palettes.hpp>
37 #include <sciplot/Plot.hpp>
38 #include <sciplot/StringOrDouble.hpp>
39 #include <sciplot/Utils.hpp>
40 #include <sciplot/specs/AxisLabelSpecs.hpp>
41 #include <sciplot/specs/BorderSpecs.hpp>
42 #include <sciplot/specs/DrawSpecs.hpp>
43 #include <sciplot/specs/FillStyleSpecs.hpp>
44 #include <sciplot/specs/FontSpecsOf.hpp>
45 #include <sciplot/specs/GridSpecs.hpp>
46 #include <sciplot/specs/HistogramStyleSpecs.hpp>
47 #include <sciplot/specs/LegendSpecs.hpp>
48 #include <sciplot/specs/LineSpecsOf.hpp>
49 #include <sciplot/specs/TicsSpecs.hpp>
50 #include <sciplot/specs/TicsSpecsMajor.hpp>
51 #include <sciplot/specs/TicsSpecsMinor.hpp>
52 
53 namespace sciplot
54 {
55 
57 class Plot2D : public Plot
58 {
59  public:
61  Plot2D();
62 
63  //======================================================================
64  // METHODS FOR DRAWING PLOT ELEMENTS
65  //======================================================================
67  template <typename X, typename... Vecs>
68  auto drawWithVecs(const std::string& with, const X&, const Vecs&... vecs) -> DrawSpecs&;
69 
71  template <typename X, typename... Vecs>
72  auto drawWithVecsContainingNaN(std::string with, const X&, const Vecs&... vecs) -> DrawSpecs&;
73 
75  template <typename X, typename Y>
76  auto drawCurve(const X& x, const Y& y) -> DrawSpecs&;
77 
79  template <typename X, typename Y>
80  auto drawCurveWithPoints(const X& x, const Y& y) -> DrawSpecs&;
81 
83  template <typename X, typename Y, typename XD>
84  auto drawCurveWithErrorBarsX(const X& x, const Y& y, const XD& xdelta) -> DrawSpecs&;
85 
87  template <typename X, typename Y, typename XL, typename XH>
88  auto drawCurveWithErrorBarsX(const X& x, const Y& y, const XL& xlow, const XH& xhigh) -> DrawSpecs&;
89 
91  template <typename X, typename Y, typename YD>
92  auto drawCurveWithErrorBarsY(const X& x, const Y& y, const YD& ydelta) -> DrawSpecs&;
93 
95  template <typename X, typename Y, typename YL, typename YH>
96  auto drawCurveWithErrorBarsY(const X& x, const Y& y, const YL& ylow, const YH& yhigh) -> DrawSpecs&;
97 
99  template <typename X, typename Y, typename XD, typename YD>
100  auto drawCurveWithErrorBarsXY(const X& x, const Y& y, const XD& xdelta, const YD& ydelta) -> DrawSpecs&;
101 
103  template <typename X, typename Y, typename XL, typename XH, typename YL, typename YH>
104  auto drawCurveWithErrorBarsXY(const X& x, const Y& y, const XL& xlow, const XH& xhigh, const YL& ylow, const YH& yhigh) -> DrawSpecs&;
105 
107  template <typename X, typename Y>
108  auto drawBrokenCurve(const X& x, const Y& y) -> DrawSpecs&;
109 
111  template <typename X, typename Y>
112  auto drawBrokenCurveWithPoints(const X& x, const Y& y) -> DrawSpecs&;
113 
115  template <typename X, typename Y>
116  auto drawCurveFilled(const X& x, const Y& y) -> DrawSpecs&;
117 
119  template <typename X, typename Y1, typename Y2>
120  auto drawCurvesFilled(const X& x, const Y1& y1, const Y2& y2) -> DrawSpecs&;
121 
123  template <typename X, typename Y>
124  auto drawBoxes(const X& x, const Y& y) -> DrawSpecs&;
125 
127  template <typename X, typename Y, typename XW>
128  auto drawBoxes(const X& x, const Y& y, const XW& xwidth) -> DrawSpecs&;
129 
131  template <typename X, typename Y, typename YD>
132  auto drawBoxesWithErrorBarsY(const X& x, const Y& y, const Y& ydelta) -> DrawSpecs&;
133 
135  template <typename X, typename Y, typename YL, typename YH>
136  auto drawBoxesWithErrorBarsY(const X& x, const Y& y, const YL& ylow, const YH& yhigh) -> DrawSpecs&;
137 
139  template <typename X, typename Y, typename XD>
140  auto drawErrorBarsX(const X& x, const Y& y, const XD& xdelta) -> DrawSpecs&;
141 
143  template <typename X, typename Y, typename XL, typename XH>
144  auto drawErrorBarsX(const X& x, const Y& y, const XL& xlow, const XH& xhigh) -> DrawSpecs&;
145 
147  template <typename X, typename Y, typename YD>
148  auto drawErrorBarsY(const X& x, const Y& y, const YD& ydelta) -> DrawSpecs&;
149 
151  template <typename X, typename Y, typename YL, typename YH>
152  auto drawErrorBarsY(const X& x, const Y& y, const YL& ylow, const YH& yhigh) -> DrawSpecs&;
153 
155  template <typename X, typename Y, typename XD, typename YD>
156  auto drawErrorBarsXY(const X& x, const Y& y, const XD& xdelta, const YD& ydelta) -> DrawSpecs&;
157 
159  template <typename X, typename Y, typename XL, typename XH, typename YL, typename YH>
160  auto drawErrorBarsXY(const X& x, const Y& y, const XL& xlow, const XH& xhigh, const YL& ylow, const YH& yhigh) -> DrawSpecs&;
161 
163  template <typename X, typename Y>
164  auto drawSteps(const X& x, const Y& y) -> DrawSpecs&;
165 
167  template <typename X, typename Y>
168  auto drawStepsChangeFirstX(const X& x, const Y& y) -> DrawSpecs&;
169 
171  template <typename X, typename Y>
172  auto drawStepsChangeFirstY(const X& x, const Y& y) -> DrawSpecs&;
173 
175  template <typename X, typename Y>
176  auto drawStepsHistogram(const X& x, const Y& y) -> DrawSpecs&;
177 
179  template <typename X, typename Y>
180  auto drawStepsFilled(const X& x, const Y& y) -> DrawSpecs&;
181 
183  template <typename X, typename Y>
184  auto drawDots(const X& x, const Y& y) -> DrawSpecs&;
185 
187  template <typename X, typename Y>
188  auto drawPoints(const X& x, const Y& y) -> DrawSpecs&;
189 
191  template <typename X, typename Y>
192  auto drawImpulses(const X& x, const Y& y) -> DrawSpecs&;
193 
195  template <typename Y>
196  auto drawHistogram(const Y& y) -> DrawSpecs&;
197 
198  //======================================================================
199  // METHODS FOR DRAWING PLOT ELEMENTS USING DATA FROM LOCAL FILES
200  //======================================================================
201 
203  auto drawWithCols(const std::string& fname, const std::string& with, const std::vector<ColumnIndex>& cols) -> DrawSpecs&;
204 
206  auto drawCurve(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&;
207 
209  auto drawCurveWithPoints(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&;
210 
212  auto drawCurveWithErrorBarsX(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xdeltacol) -> DrawSpecs&;
213 
215  auto drawCurveWithErrorBarsX(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xlowcol, ColumnIndex xhighcol) -> DrawSpecs&;
216 
218  auto drawCurveWithErrorBarsY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex ydeltacol) -> DrawSpecs&;
219 
221  auto drawCurveWithErrorBarsY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex ylowcol, ColumnIndex yhighcol) -> DrawSpecs&;
222 
224  auto drawCurveWithErrorBarsXY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xdeltacol, ColumnIndex ydeltacol) -> DrawSpecs&;
225 
227  auto drawCurveWithErrorBarsXY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xlowcol, ColumnIndex xhighcol, ColumnIndex ylowcol, ColumnIndex yhighcol) -> DrawSpecs&;
228 
230  auto drawBoxes(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&;
231 
233  auto drawBoxes(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xwidthcol) -> DrawSpecs&;
234 
236  auto drawBoxesWithErrorBarsY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex ydeltacol) -> DrawSpecs&;
237 
239  auto drawBoxesWithErrorBarsY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex ylowcol, ColumnIndex yhighcol) -> DrawSpecs&;
240 
242  auto drawErrorBarsX(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xdeltacol) -> DrawSpecs&;
243 
245  auto drawErrorBarsX(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xlowcol, ColumnIndex xhighcol) -> DrawSpecs&;
246 
248  auto drawErrorBarsY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex ydeltacol) -> DrawSpecs&;
249 
251  auto drawErrorBarsY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex ylowcol, ColumnIndex yhighcol) -> DrawSpecs&;
252 
254  auto drawErrorBarsXY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xdeltacol, ColumnIndex ydeltacol) -> DrawSpecs&;
255 
257  auto drawErrorBarsXY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xlowcol, ColumnIndex xhighcol, ColumnIndex ylowcol, ColumnIndex yhighcol) -> DrawSpecs&;
258 
260  auto drawSteps(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&;
261 
263  auto drawStepsChangeFirstX(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&;
264 
266  auto drawStepsChangeFirstY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&;
267 
269  auto drawStepsHistogram(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&;
270 
272  auto drawStepsFilled(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&;
273 
275  auto drawDots(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&;
276 
278  auto drawPoints(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&;
279 
281  auto drawImpulses(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&;
282 
284  auto drawHistogram(std::string fname, ColumnIndex ycol) -> DrawSpecs&;
285 
286  //======================================================================
287  // MISCElLANEOUS METHODS
288  //======================================================================
289 
291  auto repr() const -> std::string override;
292 };
293 
295  : Plot()
296 {
297 }
298 
299 //======================================================================
300 // METHODS FOR DRAWING PLOT ELEMENTS
301 //======================================================================
302 
303 template <typename X, typename... Vecs>
304 inline auto Plot2D::drawWithVecs(const std::string& with, const X& x, const Vecs&... vecs) -> DrawSpecs&
305 {
306  // Write the given vectors x and y as a new data set to the stream
307  std::ostringstream datastream;
308  gnuplot::writedataset(datastream, m_numdatasets, x, vecs...);
309 
310  // Set the using string to "" if X is not vector of strings.
311  // Otherwise, x contain xtics strings. Set the `using` string
312  // so that these are properly used as xtics.
313  std::string use;
314  if constexpr (internal::isStringVector<X>)
315  {
316  const auto nvecs = sizeof...(Vecs);
317  use = "0:"; // here, column 0 means the pseudo column with numbers 0, 1, 2, 3...
318  for (auto i = 2; i <= nvecs + 1; ++i)
319  use += std::to_string(i) + ":"; // this constructs 0:2:3:4:
320  use += "xtic(1)"; // this terminates the string with 0:2:3:4:xtic(1), and thus column 1 is used for the xtics
321  }
322 
323  // Append new data set to existing data
324  m_data += datastream.str();
325 
326  // Draw the data saved using a data set with index `m_numdatasets`. Increase number of data sets and set the line style specification (desired behavior is 1, 2, 3 (incrementing as new lines are plotted)).
327  return draw("'" + m_datafilename + "' index " + internal::str(m_numdatasets++), use, with).lineStyle(static_cast<int>(m_drawspecs.size()));
328 }
329 
330 template <typename X, typename... Vecs>
331 inline auto Plot2D::drawWithVecsContainingNaN(std::string with, const X& x, const Vecs&... vecs) -> DrawSpecs&
332 {
333  // Write the given vectors x and y as a new data set to the stream
334  std::ostringstream datastream;
335  gnuplot::writedataset(datastream, m_numdatasets, x, vecs...);
336 
337  std::string use;
338  const auto nvecs = sizeof...(Vecs);
339  use = "0:"; // here, column 0 means the pseudo column with numbers 0, 1, 2, 3...
340  for (auto i = 2; i <= nvecs + 1; ++i)
341  use += "($" + std::to_string(i) + "):"; // this constructs 0:$(2):$(3):$(4):
342  use += "xtic(1)"; // this terminates the string with 0:$(2):$(3):$(4):xtic(1), and thus column 1 is used for the xtics
343 
344  // Append new data set to existing data
345  m_data += datastream.str();
346 
347  // Draw the data saved using a data set with index `m_numdatasets`. Increase number of data sets and set the line style specification (desired behavior is 1, 2, 3 (incrementing as new lines are plotted)).
348  return draw("'" + m_datafilename + "' index " + internal::str(m_numdatasets++), use, with).lineStyle(static_cast<int>(m_drawspecs.size()));
349 }
350 
351 template <typename X, typename Y>
352 inline auto Plot2D::drawCurve(const X& x, const Y& y) -> DrawSpecs&
353 {
354  return drawWithVecs("lines", x, y);
355 }
356 
357 template <typename X, typename Y>
358 inline auto Plot2D::drawCurveWithPoints(const X& x, const Y& y) -> DrawSpecs&
359 {
360  return drawWithVecs("linespoints", x, y);
361 }
362 
363 template <typename X, typename Y, typename XD>
364 inline auto Plot2D::drawCurveWithErrorBarsX(const X& x, const Y& y, const XD& xdelta) -> DrawSpecs&
365 {
366  return drawWithVecs("xerrorlines", x, y, xdelta);
367 }
368 
369 template <typename X, typename Y, typename XL, typename XH>
370 inline auto Plot2D::drawCurveWithErrorBarsX(const X& x, const Y& y, const XL& xlow, const XH& xhigh) -> DrawSpecs&
371 {
372  return drawWithVecs("xerrorlines", x, y, xlow, xhigh);
373 }
374 
375 template <typename X, typename Y, typename YD>
376 inline auto Plot2D::drawCurveWithErrorBarsY(const X& x, const Y& y, const YD& ydelta) -> DrawSpecs&
377 {
378  return drawWithVecs("yerrorlines", x, y, ydelta);
379 }
380 
381 template <typename X, typename Y, typename YL, typename YH>
382 inline auto Plot2D::drawCurveWithErrorBarsY(const X& x, const Y& y, const YL& ylow, const YH& yhigh) -> DrawSpecs&
383 {
384  return drawWithVecs("yerrorlines", x, y, ylow, yhigh);
385 }
386 
387 template <typename X, typename Y, typename XD, typename YD>
388 inline auto Plot2D::drawCurveWithErrorBarsXY(const X& x, const Y& y, const XD& xdelta, const YD& ydelta) -> DrawSpecs&
389 {
390  return drawWithVecs("xyerrorlines", x, y, xdelta, ydelta);
391 }
392 
393 template <typename X, typename Y, typename XL, typename XH, typename YL, typename YH>
394 inline auto Plot2D::drawCurveWithErrorBarsXY(const X& x, const Y& y, const XL& xlow, const XH& xhigh, const YL& ylow, const YH& yhigh) -> DrawSpecs&
395 {
396  return drawWithVecs("xyerrorlines", x, y, xlow, xhigh, ylow, yhigh);
397 }
398 
399 template <typename X, typename Y>
400 inline auto Plot2D::drawBrokenCurve(const X& x, const Y& y) -> DrawSpecs&
401 {
402  return drawWithVecsContainingNaN("lines", x, y);
403 }
404 
405 template <typename X, typename Y>
406 inline auto Plot2D::drawBrokenCurveWithPoints(const X& x, const Y& y) -> DrawSpecs&
407 {
408  return drawWithVecsContainingNaN("linespoints", x, y);
409 }
410 
411 template <typename X, typename Y>
412 inline auto Plot2D::drawCurveFilled(const X& x, const Y& y) -> DrawSpecs&
413 {
414  return drawWithVecs("filledcurves", x, y);
415 }
416 
417 template <typename X, typename Y1, typename Y2>
418 inline auto Plot2D::drawCurvesFilled(const X& x, const Y1& y1, const Y2& y2) -> DrawSpecs&
419 {
420  return drawWithVecs("filledcurves", x, y1, y2);
421 }
422 
423 template <typename X, typename Y>
424 inline auto Plot2D::drawBoxes(const X& x, const Y& y) -> DrawSpecs&
425 {
426  return drawWithVecs("boxes", x, y);
427 }
428 
429 template <typename X, typename Y, typename XW>
430 inline auto Plot2D::drawBoxes(const X& x, const Y& y, const XW& xwidth) -> DrawSpecs&
431 {
432  return drawWithVecs("boxes", x, y, xwidth);
433 }
434 
435 template <typename X, typename Y, typename YD>
436 inline auto Plot2D::drawBoxesWithErrorBarsY(const X& x, const Y& y, const Y& ydelta) -> DrawSpecs&
437 {
438  return drawWithVecs("boxerrorbars", x, y, ydelta);
439 }
440 
441 template <typename X, typename Y, typename YL, typename YH>
442 inline auto Plot2D::drawBoxesWithErrorBarsY(const X& x, const Y& y, const YL& ylow, const YH& yhigh) -> DrawSpecs&
443 {
444  return drawWithVecs("boxerrorbars", x, y, ylow, yhigh);
445 }
446 
447 template <typename X, typename Y, typename XD>
448 inline auto Plot2D::drawErrorBarsX(const X& x, const Y& y, const XD& xdelta) -> DrawSpecs&
449 {
450  return drawWithVecs("xerrorbars", x, y, xdelta);
451 }
452 
453 template <typename X, typename Y, typename XL, typename XH>
454 inline auto Plot2D::drawErrorBarsX(const X& x, const Y& y, const XL& xlow, const XH& xhigh) -> DrawSpecs&
455 {
456  return drawWithVecs("xerrorbars", x, y, xlow, xhigh);
457 }
458 
459 template <typename X, typename Y, typename YD>
460 inline auto Plot2D::drawErrorBarsY(const X& x, const Y& y, const YD& ydelta) -> DrawSpecs&
461 {
462  return drawWithVecs("yerrorbars", x, y, ydelta);
463 }
464 
465 template <typename X, typename Y, typename YL, typename YH>
466 inline auto Plot2D::drawErrorBarsY(const X& x, const Y& y, const YL& ylow, const YH& yhigh) -> DrawSpecs&
467 {
468  return drawWithVecs("yerrorbars", x, y, ylow, yhigh);
469 }
470 
471 template <typename X, typename Y, typename XD, typename YD>
472 inline auto Plot2D::drawErrorBarsXY(const X& x, const Y& y, const XD& xdelta, const YD& ydelta) -> DrawSpecs&
473 {
474  return drawWithVecs("xyerrorbars", x, y, xdelta, ydelta);
475 }
476 
477 template <typename X, typename Y, typename XL, typename XH, typename YL, typename YH>
478 inline auto Plot2D::drawErrorBarsXY(const X& x, const Y& y, const XL& xlow, const XH& xhigh, const YL& ylow, const YH& yhigh) -> DrawSpecs&
479 {
480  return drawWithVecs("xyerrorbars", x, y, xlow, xhigh, ylow, yhigh);
481 }
482 
483 template <typename X, typename Y>
484 inline auto Plot2D::drawSteps(const X& x, const Y& y) -> DrawSpecs&
485 {
486  return drawWithVecsStepsChangeFirstX(x, y);
487 }
488 
489 template <typename X, typename Y>
490 inline auto Plot2D::drawStepsChangeFirstX(const X& x, const Y& y) -> DrawSpecs&
491 {
492  return drawWithVecs("steps", x, y);
493 }
494 
495 template <typename X, typename Y>
496 inline auto Plot2D::drawStepsChangeFirstY(const X& x, const Y& y) -> DrawSpecs&
497 {
498  return drawWithVecs("fsteps", x, y);
499 }
500 
501 template <typename X, typename Y>
502 inline auto Plot2D::drawStepsHistogram(const X& x, const Y& y) -> DrawSpecs&
503 {
504  return drawWithVecs("histeps", x, y);
505 }
506 
507 template <typename X, typename Y>
508 inline auto Plot2D::drawStepsFilled(const X& x, const Y& y) -> DrawSpecs&
509 {
510  return drawWithVecs("fillsteps", x, y);
511 }
512 
513 template <typename X, typename Y>
514 inline auto Plot2D::drawDots(const X& x, const Y& y) -> DrawSpecs&
515 {
516  return drawWithVecs("dots", x, y);
517 }
518 
519 template <typename X, typename Y>
520 inline auto Plot2D::drawPoints(const X& x, const Y& y) -> DrawSpecs&
521 {
522  return drawWithVecs("points", x, y);
523 }
524 
525 template <typename X, typename Y>
526 inline auto Plot2D::drawImpulses(const X& x, const Y& y) -> DrawSpecs&
527 {
528  return drawWithVecs("impulses", x, y);
529 }
530 
531 template <typename Y>
532 inline auto Plot2D::drawHistogram(const Y& y) -> DrawSpecs&
533 {
534  return drawWithVecs("", y); // empty string because we rely on `set style data histograms` since relying `with histograms` is not working very well (e.g., empty key/lenged appearing in columnstacked mode).
535 }
536 
537 //======================================================================
538 // METHODS FOR DRAWING PLOT ELEMENTS USING DATA FROM LOCAL FILES
539 //======================================================================
540 
541 inline auto Plot2D::drawWithCols(const std::string& fname, const std::string& with, const std::vector<ColumnIndex>& cols) -> DrawSpecs&
542 {
543  std::string use;
544  for (const auto& col : cols)
545  use += col.value + ":"; // e.g., "1:4:5:7:" (where 1 is x, 4 is y, 5 is ylow and 7 is yhigh for a yerrorlines plot)
546  use = internal::trimright(use, ':'); // e.g., "1:4:5:7:" => "1:4:5:7"
547  std::string what = "'" + fname + "'"; // e.g., "'myfile.dat'"
548  return draw(what, use, with).lineStyle(static_cast<int>(m_drawspecs.size())); // e.g., draw(what="'myfile.dat'", use="1:2", with="lines");
549 }
550 
551 inline auto Plot2D::drawCurve(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&
552 {
553  return drawWithCols(fname, "lines", {xcol, ycol});
554 }
555 
556 inline auto Plot2D::drawCurveWithPoints(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&
557 {
558  return drawWithCols(fname, "linespoints", {xcol, ycol});
559 }
560 
561 inline auto Plot2D::drawCurveWithErrorBarsX(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xdeltacol) -> DrawSpecs&
562 {
563  return drawWithCols(fname, "xerrorlines", {xcol, ycol, xdeltacol});
564 }
565 
566 inline auto Plot2D::drawCurveWithErrorBarsX(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xlowcol, ColumnIndex xhighcol) -> DrawSpecs&
567 {
568  return drawWithCols(fname, "xerrorlines", {xcol, ycol, xlowcol, xhighcol});
569 }
570 
571 inline auto Plot2D::drawCurveWithErrorBarsY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex ydeltacol) -> DrawSpecs&
572 {
573  return drawWithCols(fname, "yerrorlines", {xcol, ycol, ydeltacol});
574 }
575 
576 inline auto Plot2D::drawCurveWithErrorBarsY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex ylowcol, ColumnIndex yhighcol) -> DrawSpecs&
577 {
578  return drawWithCols(fname, "yerrorlines", {xcol, ycol, ylowcol, yhighcol});
579 }
580 
581 inline auto Plot2D::drawCurveWithErrorBarsXY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xdeltacol, ColumnIndex ydeltacol) -> DrawSpecs&
582 {
583  return drawWithCols(fname, "xyerrorlines", {xcol, ycol, xdeltacol, ydeltacol});
584 }
585 
586 inline auto Plot2D::drawCurveWithErrorBarsXY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xlowcol, ColumnIndex xhighcol, ColumnIndex ylowcol, ColumnIndex yhighcol) -> DrawSpecs&
587 {
588  return drawWithCols(fname, "xyerrorlines", {xcol, ycol, xlowcol, xhighcol, ylowcol, yhighcol});
589 }
590 
591 inline auto Plot2D::drawBoxes(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&
592 {
593  return drawWithCols(fname, "boxes", {xcol, ycol});
594 }
595 
596 inline auto Plot2D::drawBoxes(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xwidthcol) -> DrawSpecs&
597 {
598  return drawWithCols(fname, "boxes", {xcol, ycol, xwidthcol});
599 }
600 
601 inline auto Plot2D::drawBoxesWithErrorBarsY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex ydeltacol) -> DrawSpecs&
602 {
603  return drawWithCols(fname, "boxerrorbars", {xcol, ycol, ydeltacol});
604 }
605 
606 inline auto Plot2D::drawBoxesWithErrorBarsY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex ylowcol, ColumnIndex yhighcol) -> DrawSpecs&
607 {
608  return drawWithCols(fname, "boxerrorbars", {xcol, ycol, ylowcol, yhighcol});
609 }
610 
611 inline auto Plot2D::drawErrorBarsX(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xdeltacol) -> DrawSpecs&
612 {
613  return drawWithCols(fname, "xerrorbars", {xcol, ycol, xdeltacol});
614 }
615 
616 inline auto Plot2D::drawErrorBarsX(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xlowcol, ColumnIndex xhighcol) -> DrawSpecs&
617 {
618  return drawWithCols(fname, "xerrorbars", {xcol, ycol, xlowcol, xhighcol});
619 }
620 
621 inline auto Plot2D::drawErrorBarsY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex ydeltacol) -> DrawSpecs&
622 {
623  return drawWithCols(fname, "yerrorbars", {xcol, ycol, ydeltacol});
624 }
625 
626 inline auto Plot2D::drawErrorBarsY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex ylowcol, ColumnIndex yhighcol) -> DrawSpecs&
627 {
628  return drawWithCols(fname, "yerrorbars", {xcol, ycol, ylowcol, yhighcol});
629 }
630 
631 inline auto Plot2D::drawErrorBarsXY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xdeltacol, ColumnIndex ydeltacol) -> DrawSpecs&
632 {
633  return drawWithCols(fname, "xyerrorbars", {xcol, ycol, xdeltacol, ydeltacol});
634 }
635 
636 inline auto Plot2D::drawErrorBarsXY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol, ColumnIndex xlowcol, ColumnIndex xhighcol, ColumnIndex ylowcol, ColumnIndex yhighcol) -> DrawSpecs&
637 {
638  return drawWithCols(fname, "xyerrorbars", {xcol, ycol, xlowcol, xhighcol, ylowcol, yhighcol});
639 }
640 
641 inline auto Plot2D::drawSteps(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&
642 {
643  return drawWithCols(fname, "steps", {xcol, ycol});
644 }
645 
646 inline auto Plot2D::drawStepsChangeFirstX(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&
647 {
648  return drawWithCols(fname, "steps", {xcol, ycol});
649 }
650 
651 inline auto Plot2D::drawStepsChangeFirstY(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&
652 {
653  return drawWithCols(fname, "fsteps", {xcol, ycol});
654 }
655 
656 inline auto Plot2D::drawStepsHistogram(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&
657 {
658  return drawWithCols(fname, "histeps", {xcol, ycol});
659 }
660 
661 inline auto Plot2D::drawStepsFilled(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&
662 {
663  return drawWithCols(fname, "fillsteps", {xcol, ycol});
664 }
665 
666 inline auto Plot2D::drawDots(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&
667 {
668  return drawWithCols(fname, "dots", {xcol, ycol});
669 }
670 
671 inline auto Plot2D::drawPoints(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&
672 {
673  return drawWithCols(fname, "points", {xcol, ycol});
674 }
675 
676 inline auto Plot2D::drawImpulses(const std::string& fname, ColumnIndex xcol, ColumnIndex ycol) -> DrawSpecs&
677 {
678  return drawWithCols(fname, "impulses", {xcol, ycol});
679 }
680 
681 inline auto Plot2D::drawHistogram(std::string fname, ColumnIndex ycol) -> DrawSpecs&
682 {
683  return drawWithCols(fname, "", {ycol});
684 }
685 
686 //======================================================================
687 // MISCElLANEOUS METHODS
688 //======================================================================
689 
690 inline auto Plot2D::repr() const -> std::string
691 {
692  std::stringstream script;
693  // Add plot setup commands
694  script << "#==============================================================================" << std::endl;
695  script << "# SETUP COMMANDS" << std::endl;
696  script << "#==============================================================================" << std::endl;
697  // Add palette info if a palette was set
698  if (!m_palette.empty())
699  {
700  gnuplot::palettecmd(script, m_palette);
701  }
702  script << gnuplot::cmdValueStr("set xrange", m_xrange);
703  script << gnuplot::cmdValueStr("set yrange", m_yrange);
704  script << m_xlabel << std::endl;
705  script << m_ylabel << std::endl;
706  script << m_rlabel << std::endl;
707  script << m_border << std::endl;
708  script << m_grid << std::endl;
709  script << m_style_fill << std::endl;
710  script << m_style_histogram << std::endl;
711  script << m_tics << std::endl;
712  script << m_xtics_major_bottom << std::endl;
713  script << m_xtics_major_top << std::endl;
714  script << m_xtics_minor_bottom << std::endl;
715  script << m_xtics_minor_top << std::endl;
716  script << m_ytics_major_left << std::endl;
717  script << m_ytics_major_right << std::endl;
718  script << m_ytics_minor_left << std::endl;
719  script << m_ytics_minor_right << std::endl;
720  script << m_ztics_major << std::endl;
721  script << m_ztics_minor << std::endl;
722  script << m_rtics_major << std::endl;
723  script << m_rtics_minor << std::endl;
724  script << m_legend << std::endl;
725  script << gnuplot::cmdValueStr("set boxwidth", m_boxwidth);
726  script << gnuplot::cmdValueStr("set samples", m_samples);
727  script << gnuplot::cmdValueStr("set datafile missing", MISSING_INDICATOR);
728  // Add custom gnuplot commands
729  if (!m_customcmds.empty())
730  {
731  script << "#==============================================================================" << std::endl;
732  script << "# CUSTOM EXPLICIT GNUPLOT COMMANDS" << std::endl;
733  script << "#==============================================================================" << std::endl;
734  for (const auto& c : m_customcmds)
735  {
736  script << c << std::endl;
737  }
738  }
739  // Add the actual plot commands for all drawXYZ() calls
740  script << "#==============================================================================" << std::endl;
741  script << "# PLOT COMMANDS" << std::endl;
742  script << "#==============================================================================" << std::endl;
743  script << "plot \\\n"; // use `\` to have a plot command in each individual line!
744  // Write plot commands and style per plot
745  const auto n = m_drawspecs.size();
746  for (std::size_t i = 0; i < n; ++i)
747  {
748  script << " " << m_drawspecs[i] << (i < n - 1 ? ", \\\n" : ""); // consider indentation with 4 spaces!
749  }
750  // Add an empty line after plots
751  script << std::endl;
752  // unset palette info if a palette was set
753  if (!m_palette.empty())
754  {
755  gnuplot::unsetpalettecmd(script);
756  }
757  // Add an empty line at the end
758  script << std::endl;
759  return script.str();
760 }
761 
762 } // namespace sciplot
Plot2D()
Construct a default Plot object.
Definition: Plot2D.hpp:294
auto drawWithVecs(const std::string &with, const X &, const Vecs &... vecs) -> DrawSpecs &
Draw plot object with given style and given vectors (e.g., plot.draw("lines", x, y)).
Definition: Plot2D.hpp:304
TicsSpecsMajor m_ytics_major_left
The specs for the major ytics at the left.
Definition: Plot.hpp:227
AxisLabelSpecs m_rlabel
The label of the r-axis.
Definition: Plot.hpp:237
auto drawBoxes(const X &x, const Y &y) -> DrawSpecs &
Draw boxes with given x and y vectors.
Definition: Plot2D.hpp:424
auto repr() const -> std::string override
Convert this plot object into a gnuplot formatted string.
Definition: Plot2D.hpp:690
auto drawPoints(const X &x, const Y &y) -> DrawSpecs &
Draw points with given x and y vectors.
Definition: Plot2D.hpp:520
auto drawWithVecsContainingNaN(std::string with, const X &, const Vecs &... vecs) -> DrawSpecs &
Draw plot object with given style and given vectors (e.g., plot.draw("lines", x, y)) that may contain...
Definition: Plot2D.hpp:331
std::string m_xrange
The x-range of the plot as a gnuplot formatted string (e.g., "set xrange [0:1]")
Definition: Plot.hpp:219
auto drawImpulses(const X &x, const Y &y) -> DrawSpecs &
Draw impulses with given x and y vectors.
Definition: Plot2D.hpp:526
LegendSpecs m_legend
The legend specs of the plot.
Definition: Plot.hpp:241
std::string m_samples
The number of sample points for functions.
Definition: Plot.hpp:240
auto drawDots(const X &x, const Y &y) -> DrawSpecs &
Draw dots with given x and y vectors.
Definition: Plot2D.hpp:514
TicsSpecs m_tics
The specs of the tics of the plot.
Definition: Plot.hpp:222
std::string m_palette
The name of the gnuplot palette to be used.
Definition: Plot.hpp:210
auto drawBrokenCurveWithPoints(const X &x, const Y &y) -> DrawSpecs &
Draw a curve with points with given x and y vectors, breaking this curve whenever NaN is found in x o...
Definition: Plot2D.hpp:406
GridSpecs m_grid
The vector of grid specs for the major and minor grid lines in the plot (for xtics,...
Definition: Plot.hpp:218
FillStyleSpecs m_style_fill
The specs for the fill style of the plot elements in the plot that can be painted.
Definition: Plot.hpp:239
auto drawCurvesFilled(const X &x, const Y1 &y1, const Y2 &y2) -> DrawSpecs &
Draw curves with given x, y1 and y2 vectors with filled areas above / below / between curves.
Definition: Plot2D.hpp:418
auto drawErrorBarsX(const X &x, const Y &y, const XD &xdelta) -> DrawSpecs &
Draw error bars along x with given x, y, and xdelta vectors.
Definition: Plot2D.hpp:448
TicsSpecsMajor m_xtics_major_top
The specs for the major xtics at the top.
Definition: Plot.hpp:224
auto drawStepsFilled(const X &x, const Y &y) -> DrawSpecs &
Draw steps with given x and y vectors with filled area below steps.
Definition: Plot2D.hpp:508
auto drawCurveFilled(const X &x, const Y &y) -> DrawSpecs &
Draw curves with given x and y vectors with filled areas above / below axes.
Definition: Plot2D.hpp:412
AxisLabelSpecs m_xlabel
The label of the x-axis.
Definition: Plot.hpp:235
auto drawCurveWithPoints(const X &x, const Y &y) -> DrawSpecs &
Draw a curve with points with given x and y vectors.
Definition: Plot2D.hpp:358
auto drawStepsChangeFirstY(const X &x, const Y &y) -> DrawSpecs &
Draw steps with given x and y vectors with steps along y changes first.
Definition: Plot2D.hpp:496
TicsSpecsMajor m_ztics_major
The specs for the major ztics.
Definition: Plot.hpp:231
auto drawErrorBarsY(const X &x, const Y &y, const YD &ydelta) -> DrawSpecs &
Draw error bars along y with given x, y, and ydelta vectors.
Definition: Plot2D.hpp:460
auto drawWithCols(const std::string &fname, const std::string &with, const std::vector< ColumnIndex > &cols) -> DrawSpecs &
Draw plot object with given style and given vectors (e.g., plot.draw("lines", x, y)).
Definition: Plot2D.hpp:541
auto drawCurveWithErrorBarsX(const X &x, const Y &y, const XD &xdelta) -> DrawSpecs &
Draw a curve with error bars along x with given x, y, and xdelta vectors.
Definition: Plot2D.hpp:364
auto drawErrorBarsXY(const X &x, const Y &y, const XD &xdelta, const YD &ydelta) -> DrawSpecs &
Draw error bars along x and y with given x, y, xdelta, and ydelta vectors.
Definition: Plot2D.hpp:472
auto drawBoxesWithErrorBarsY(const X &x, const Y &y, const Y &ydelta) -> DrawSpecs &
Draw boxes with error bars along y with given x, y, ydelta vectors.
Definition: Plot2D.hpp:436
AxisLabelSpecs m_ylabel
The label of the y-axis.
Definition: Plot.hpp:236
auto drawCurveWithErrorBarsY(const X &x, const Y &y, const YD &ydelta) -> DrawSpecs &
Draw a curve with error bars along y with given x, y, and ydelta vectors.
Definition: Plot2D.hpp:376
std::string m_boxwidth
The default width of boxes in plots containing boxes without given widths.
Definition: Plot.hpp:238
An auxiliary type used to represent a data column index.
Definition: ColumnIndex.hpp:35
auto drawBrokenCurve(const X &x, const Y &y) -> DrawSpecs &
Draw a curve with given x and y vectors, breaking this curve whenever NaN is found in x or y.
Definition: Plot2D.hpp:400
TicsSpecsMinor m_xtics_minor_bottom
The specs for the minor xtics at the bottom.
Definition: Plot.hpp:225
TicsSpecsMinor m_ytics_minor_left
The specs for the minor ytics at the left.
Definition: Plot.hpp:229
TicsSpecsMinor m_xtics_minor_top
The specs for the minor xtics at the top.
Definition: Plot.hpp:226
TicsSpecsMinor m_ztics_minor
The specs for the minor ztics.
Definition: Plot.hpp:232
TicsSpecsMajor m_ytics_major_right
The specs for the major ytics at the right.
Definition: Plot.hpp:228
auto drawCurve(const X &x, const Y &y) -> DrawSpecs &
Draw a curve with given x and y vectors.
Definition: Plot2D.hpp:352
TicsSpecsMajor m_xtics_major_bottom
The specs for the major xtics at the bottom.
Definition: Plot.hpp:223
auto drawStepsHistogram(const X &x, const Y &y) -> DrawSpecs &
Draw steps with given x and y vectors in a histogram style.
Definition: Plot2D.hpp:502
The class used to create a plot containing graphical elements.
Definition: Plot.hpp:57
auto drawHistogram(const Y &y) -> DrawSpecs &
Draw a histogram for the given y vector.
Definition: Plot2D.hpp:532
The class used to create a plot containing graphical elements.
Definition: Plot2D.hpp:58
auto drawStepsChangeFirstX(const X &x, const Y &y) -> DrawSpecs &
Draw steps with given x and y vectors with steps along x changes first.
Definition: Plot2D.hpp:490
std::string m_yrange
The y-range of the plot as a gnuplot formatted string (e.g., "set yrange [0:1]")
Definition: Plot.hpp:220
HistogramStyleSpecs m_style_histogram
The specs for the histogram style of the plot.
Definition: Plot.hpp:221
std::vector< std::string > m_customcmds
The strings containing gnuplot custom commands.
Definition: Plot.hpp:243
The class where options for the plotted element can be specified.
Definition: DrawSpecs.hpp:41
TicsSpecsMinor m_rtics_minor
The specs for the minor rtics.
Definition: Plot.hpp:234
TicsSpecsMajor m_rtics_major
The specs for the major rtics.
Definition: Plot.hpp:233
auto drawSteps(const X &x, const Y &y) -> DrawSpecs &
Draw steps with given x and y vectors. Identical to drawStepsChangeFirstX.
Definition: Plot2D.hpp:484
auto drawCurveWithErrorBarsXY(const X &x, const Y &y, const XD &xdelta, const YD &ydelta) -> DrawSpecs &
Draw a curve with error bars along x and y with given x, y, xdelta, and ydelta vectors.
Definition: Plot2D.hpp:388
std::vector< DrawSpecs > m_drawspecs
The plot specs for each call to gnuplot plot function.
Definition: Plot.hpp:242
BorderSpecs m_border
The border style of the plot.
Definition: Plot.hpp:217
TicsSpecsMinor m_ytics_minor_right
The specs for the minor ytics at the right.
Definition: Plot.hpp:230