Skip to content

Feature/error bar #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions gallery/lines_bars_and_markers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ add_demo(fill_between_demo fill_between_demo.cpp)
add_demo(fill_betweenx_demo fill_betweenx_demo.cpp)
add_demo(scatter_with_legend scatter_with_legend.cpp)
add_demo(scatter_hist scatter_hist.cpp)
add_demo(errorbar_limits_simple errorbar_limits_simple.cpp)
add_demo(errorbar_subsample errorbar_subsample.cpp)

# TODO: macro for this!
add_custom_target(lines_bars_and_markers
DEPENDS bar_label_demo fill simple_plot scatter_symbol fill_between_demo fill_betweenx_demo scatter_with_legend scatter_hist
DEPENDS bar_label_demo fill simple_plot scatter_symbol fill_between_demo fill_betweenx_demo scatter_with_legend scatter_hist errorbar_limits_simple errorbar_subsample
COMMAND bar_label_demo
COMMAND fill
COMMAND simple_plot
Expand All @@ -18,6 +19,8 @@ add_custom_target(lines_bars_and_markers
COMMAND fill_betweenx_demo
COMMAND scatter_with_legend
COMMAND scatter_hist
COMMAND errorbar_limits_simple
COMMAND errorbar_subsample
COMMENT "running lines_bars_and_markers"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../images"
)
54 changes: 54 additions & 0 deletions gallery/lines_bars_and_markers/errorbar_limits_simple.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// example
// https://matplotlib.org/stable/gallery/lines_bars_and_markers/errorbar_limits_simple.html

#include <pybind11/embed.h>
#include <pybind11/stl.h>

#include <matplotlibcpp17/pyplot.h>

#include <xtensor/xbuilder.hpp>
#include <xtensor/xmath.hpp>

#include <vector>

namespace py = pybind11;
using namespace py::literals;
using namespace std;
using namespace matplotlibcpp17;

int main() {
py::scoped_interpreter guard{};
auto plt = pyplot::import();
auto fig = plt.figure();
auto x_ = xt::arange(0.0, 10.0, 1.0);
auto y_ = 2.5 * xt::sin(x_ / 20 * M_PI);
auto y1_ = y_ + 1.0, y2_ = y_ + 2.0, y3_ = y_ + 3.0;
auto yerr_ = xt::linspace(0.05, 0.2, 10);
vector<double> x(x_.begin(), x_.end()), y(y_.begin(), y_.end()),
yerr(yerr_.begin(), yerr_.end()), y3(y3_.begin(), y3_.end()),
y2(y2_.begin(), y2_.end()), y1(y1_.begin(), y1_.end());
plt.errorbar(Args(x, y3),
Kwargs("yerr"_a = yerr, "label"_a = "both limits (default)"));
plt.errorbar(Args(x, y2), Kwargs("yerr"_a = yerr, "uplims"_a = true,
"label"_a = "uplims=True"));
plt.errorbar(Args(x, y1),
Kwargs("yerr"_a = yerr, "uplims"_a = true, "lolims"_a = true,
"label"_a = "uplims=True, lolims=True"));

vector<bool> upperlimits, lowerlimits;
for (auto i : {0, 1, 2, 3, 4}) {
upperlimits.push_back(true);
upperlimits.push_back(false);
lowerlimits.push_back(false);
lowerlimits.push_back(true);
}
plt.errorbar(Args(x, y), Kwargs("yerr"_a = yerr, "uplims"_a = upperlimits,
"lolims"_a = lowerlimits,
"label"_a = "subsets of uplims and lolims"));
plt.legend(Args(), Kwargs("loc"_a = "lower right"));
#if USE_GUI
plt.show();
#else
plt.savefig(Args("errorbar_limits_simple.png"));
#endif
}
54 changes: 54 additions & 0 deletions gallery/lines_bars_and_markers/errorbar_subsample.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// example from
// https://matplotlib.org/stable/gallery/lines_bars_and_markers/errorbar_subsample.html

#include <pybind11/embed.h>
#include <pybind11/stl.h>

#include <matplotlibcpp17/pyplot.h>

#include <xtensor/xbuilder.hpp>
#include <xtensor/xmath.hpp>

#include <vector>

namespace py = pybind11;
using namespace py::literals;
using namespace std;
using namespace matplotlibcpp17;

int main() {
auto x_ = xt::arange(0.1, 4.0, 0.1);
auto y1_ = xt::exp(-1.0 * x_);
auto y2_ = xt::exp(-0.5 * x_);
auto y1err_ = 0.1 + 0.1 * xt::sqrt(x_);
auto y2err_ = 0.1 + 0.1 * xt::sqrt(x_ / 2.0);
vector<double> x(x_.begin(), x_.end()), y1(y1_.begin(), y1_.end()),
y2(y2_.begin(), y2_.end()), y1err(y1err_.begin(), y1err_.end()),
y2err(y2err_.begin(), y2err_.end());

py::scoped_interpreter guard{};
auto plt = pyplot::import();
auto [fig, axs] = plt.subplots(
1, 3, Kwargs("sharex"_a = true, "figsize"_a = py::make_tuple(12, 6)));
auto ax0 = axs[0], ax1 = axs[1], ax2 = axs[2];
ax0.set_title(Args("all errorbars"));
ax0.errorbar(Args(x, y1), Kwargs("yerr"_a = y1err));
ax0.errorbar(Args(x, y1), Kwargs("yerr"_a = y2err));

ax1.set_title(Args("only every 6th errorbar"));
ax1.errorbar(Args(x, y1), Kwargs("yerr"_a = y1err, "errorevery"_a = 6));
ax1.errorbar(Args(x, y2), Kwargs("yerr"_a = y2err, "errorevery"_a = 6));

ax2.set_title(Args("second seris shifted by 3"));
ax2.errorbar(Args(x, y1),
Kwargs("yerr"_a = y1err, "errorevery"_a = py::make_tuple(0, 6)));
ax2.errorbar(Args(x, y2),
Kwargs("yerr"_a = y2err, "errorevery"_a = py::make_tuple(3, 6)));

fig.suptitle(Args("Errorbar subsampling"));
#if USE_GUI
plt.show();
#else
plt.savefig(Args("erorbar_subsample.png"));
#endif
}
4 changes: 3 additions & 1 deletion gallery/mplot3d/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ add_demo(lines3d lines3d.cpp)
add_demo(lorenz_attractor lorenz_attractor.cpp)
add_demo(contour3d contour3d.cpp)
add_demo(subplot3d subplot3d.cpp)
add_demo(errorbar3d errorbar3d.cpp)

add_custom_target(mplot3d
DEPENDS lines3d lorenz_attractor contour3d subplot3d
DEPENDS lines3d lorenz_attractor contour3d subplot3d errorbar3d
COMMAND lines3d
COMMAND lorenz_attractor
COMMAND contour3d
COMMAND subplot3d
COMMAND errorbar3d
COMMENT "running mplot3d"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../images"
)
49 changes: 49 additions & 0 deletions gallery/mplot3d/errorbar3d.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// example from https://matplotlib.org/stable/gallery/mplot3d/errorbar3d.html

#include <pybind11/embed.h>
#include <pybind11/stl.h>

#include <matplotlibcpp17/pyplot.h>

#include <xtensor/xbuilder.hpp>
#include <xtensor/xmath.hpp>

#include <vector>
#include <algorithm>

namespace py = pybind11;
using namespace py::literals;
using namespace std;
using namespace matplotlibcpp17;

int main() {
py::scoped_interpreter guard{};
auto plt = pyplot::import();
auto ax = plt.figure().add_subplot(Args(), Kwargs("projection"_a = "3d"));
auto t_ = xt::arange(0.0, 2 * M_PI + 0.1, 0.01);
auto x_ = xt::sin(1.0 * t_);
auto y_ = xt::cos(3.0 * t_);
auto z_ = xt::sin(5.0 * t_);
vector<double> t(t_.begin(), t_.end()), x(x_.begin(), x_.end()),
y(y_.begin(), y_.end()), z(z_.begin(), z_.end());

const int estep = 15;
vector<int> i, zuplims, zlolims;
std::iota(i.begin(), i.end(), 0);
std::transform(i.begin(), i.end(), std::back_inserter(zuplims), [](int i) {
return (i % 15 == 0) and ((i / estep) % 3 == 0);
});
std::transform(i.begin(), i.end(), std::back_inserter(zlolims), [](int i) {
return (i % 15 == 0) and ((i / estep) % 3 == 2);
});

ax.errorbar(Args(x, y, z, 0.2),
Kwargs("zuplims"_a = zuplims, "zlolims"_a = zlolims,
"errorevery"_a = estep));

ax.set_xlabel(Args("X label"));
ax.set_ylabel(Args("Y label"));
ax.set_zlabel(Args("Z label"));

plt.show();
}
4 changes: 3 additions & 1 deletion gallery/statistics/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
add_demo(hist hist.cpp)
add_demo(errorbar errorbar.cpp)

add_custom_target(statitics
DEPENDS hist
DEPENDS hist errorbar
COMMAND hist
COMMAND errorbar
COMMENT "running hist"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../images"
)
31 changes: 31 additions & 0 deletions gallery/statistics/errorbar.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// example from https://matplotlib.org/stable/gallery/statistics/errorbar.html

#include <pybind11/embed.h>
#include <pybind11/stl.h>

#include <matplotlibcpp17/pyplot.h>

#include <xtensor/xrandom.hpp>

#include <random>

namespace py = pybind11;
using namespace py::literals;
using namespace std;
using namespace matplotlibcpp17;

int main() {
py::scoped_interpreter guard{};
auto plt = pyplot::import();
auto x_ = xt::arange(0.1, 4.0, 0.5);
auto y_ = xt::exp(-x_);
vector<double> x(x_.begin(), x_.end()), y(y_.begin(), y_.end());

auto [fig, ax] = plt.subplots();
ax.errorbar(Args(x, y), Kwargs("xerr"_a = 0.2, "yerr"_a = 0.4));
#if USE_GUI
plt.show();
#else
plt.savefig(Args("erorrbar.png"));
#endif
}
24 changes: 23 additions & 1 deletion include/matplotlibcpp17/axes.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ struct DECL_STRUCT_ATTR Axes : public BaseWrapper {
pybind11::object contour(const pybind11::tuple &args = pybind11::tuple(),
const pybind11::dict &kwargs = pybind11::dict());

// errorbar
pybind11::object errorbar(const pybind11::tuple &args = pybind11::tuple(),
const pybind11::dict &kwargs = pybind11::dict());

// fill
pybind11::object fill(const pybind11::tuple &args = pybind11::tuple(),
const pybind11::dict &kwargs = pybind11::dict());
Expand Down Expand Up @@ -213,6 +217,7 @@ struct DECL_STRUCT_ATTR Axes : public BaseWrapper {
#endif
LOAD_FUNC_ATTR(barh, self);
LOAD_FUNC_ATTR(contour, self);
LOAD_FUNC_ATTR(errorbar, self);
LOAD_FUNC_ATTR(fill, self);
LOAD_FUNC_ATTR(fill_between, self);
LOAD_FUNC_ATTR(fill_betweenx, self);
Expand All @@ -232,8 +237,10 @@ struct DECL_STRUCT_ATTR Axes : public BaseWrapper {
plot_wireframe_attr = self.attr("plot_wireframe");
set_zlabel_attr = self.attr("set_zlabel");
INFO_MSG("Loaded Axes3D");
projection_3d = true;
} catch (...) {
projection_3d = false;
}
catch(...) {}
LOAD_FUNC_ATTR(quiver, self);
LOAD_FUNC_ATTR(quiverkey, self);
LOAD_FUNC_ATTR(scatter, self);
Expand All @@ -258,6 +265,7 @@ struct DECL_STRUCT_ATTR Axes : public BaseWrapper {
pybind11::object bar_label_attr;
pybind11::object barh_attr;
pybind11::object contour_attr;
pybind11::object errorbar_attr;
pybind11::object fill_attr;
pybind11::object fill_between_attr;
pybind11::object fill_betweenx_attr;
Expand Down Expand Up @@ -289,6 +297,7 @@ struct DECL_STRUCT_ATTR Axes : public BaseWrapper {
pybind11::object set_zlabel_attr;
pybind11::object text_attr;
pybind11::object tick_params_attr;
bool projection_3d;
};

// add_artist
Expand Down Expand Up @@ -353,6 +362,19 @@ pybind11::object Axes::contour(const pybind11::tuple &args,
return obj;
}

// errorbar
pybind11::object Axes::errorbar(const pybind11::tuple &args,
const pybind11::dict &kwargs) {
if (not projection_3d) {
pybind11::object obj = errorbar_attr(*args, **kwargs);
return obj;
} else {
ERROR_MSG("Call to errorbar with projection='3d' is invalid because "
"matplotlib version is < 3.4.0");
std::exit(0);
}
}

// fill
pybind11::object Axes::fill(const pybind11::tuple &args,
const pybind11::dict &kwargs) {
Expand Down
13 changes: 13 additions & 0 deletions include/matplotlibcpp17/pyplot.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ struct DECL_STRUCT_ATTR PyPlot {
pybind11::object clf(const pybind11::tuple &args = pybind11::tuple(),
const pybind11::dict &kwargs = pybind11::dict());

// errorbar
pybind11::object errorbar(const pybind11::tuple &args = pybind11::tuple(),
const pybind11::dict &kwargs = pybind11::dict());

// figaspect
std::tuple<double, double>
figaspect(const pybind11::tuple &args = pybind11::tuple(),
Expand Down Expand Up @@ -118,6 +122,7 @@ struct DECL_STRUCT_ATTR PyPlot {
LOAD_FUNC_ATTR(axis, mod);
LOAD_FUNC_ATTR(cla, mod);
LOAD_FUNC_ATTR(clf, mod);
LOAD_FUNC_ATTR(errorbar, mod);
LOAD_FUNC_ATTR(figaspect, mod);
LOAD_FUNC_ATTR(figure, mod);
LOAD_FUNC_ATTR(gca, mod);
Expand All @@ -141,6 +146,7 @@ struct DECL_STRUCT_ATTR PyPlot {
pybind11::object axis_attr;
pybind11::object cla_attr;
pybind11::object clf_attr;
pybind11::object errorbar_attr;
pybind11::object figaspect_attr;
pybind11::object figure_attr;
pybind11::object gca_attr;
Expand Down Expand Up @@ -187,6 +193,13 @@ pybind11::object PyPlot::clf(const pybind11::tuple &args,
return ret;
}

// errorbar
pybind11::object PyPlot::errorbar(const pybind11::tuple &args,
const pybind11::dict &kwargs) {
pybind11::object ret = errorbar_attr(*args, **kwargs);
return ret;
}

// figaspect
std::tuple<double, double> PyPlot::figaspect(const pybind11::tuple &args,
const pybind11::dict &kwargs) {
Expand Down