[python] Matplotlib: handle 'auto' range computation

This commit is contained in:
Émilie Feral
2020-03-26 11:41:35 +01:00
parent fb3f6ab6f3
commit 8aa1930f80
2 changed files with 63 additions and 0 deletions

View File

@@ -4,6 +4,7 @@ namespace Matplotlib {
PlotStore::PlotStore() : Shared::InteractiveCurveViewRange(),
m_axesRequested(true),
m_axesAuto(true),
m_gridRequested(false)
{
flush();
@@ -14,6 +15,9 @@ void PlotStore::flush() {
m_segments = mp_obj_new_list(0, nullptr);
m_rects = mp_obj_new_list(0, nullptr);
m_labels = mp_obj_new_list(0, nullptr);
m_axesRequested = true;
m_axesAuto = true;
m_gridRequested = false;
}
// Iterators
@@ -133,4 +137,61 @@ void PlotStore::addLabel(mp_obj_t x, mp_obj_t y, mp_obj_t string) {
mp_obj_list_append(m_labels, tuple);
}
// Axes
static inline float minFloat(float x, float y) { return x < y ? x : y; }
static inline float maxFloat(float x, float y) { return x > y ? x : y; }
void updateRange(float * xMin, float * xMax, float * yMin, float * yMax, float x, float y) {
if (!std::isnan(x) && !std::isinf(x) && !std::isnan(y) && !std::isinf(y)) {
*xMin = minFloat(*xMin, x);
*xMax = maxFloat(*xMax, x);
*yMin = minFloat(*yMin, y);
*yMax = maxFloat(*yMax, y);
}
}
void checkPositiveRangeAndAddMargin(float * min, float * max) {
if (*min > *max) {
*min = - Shared::Range1D::k_default;
*max = Shared::Range1D::k_default;
return;
}
// Add margins
float margin = (*max - *min)/10.0f;
*min -= margin;
*max += margin;
}
void PlotStore::initRange() {
if (m_axesAuto) {
float xMin = FLT_MAX;
float xMax = -FLT_MAX;
float yMin = FLT_MAX;
float yMax = -FLT_MAX;
for (PlotStore::Dot dot : dots()) {
updateRange(&xMin, &xMax, &yMin, &yMax, dot.x(), dot.y());
}
for (PlotStore::Label label : labels()) {
updateRange(&xMin, &xMax, &yMin, &yMax, label.x(), label.y());
}
for (PlotStore::Segment segment : segments()) {
updateRange(&xMin, &xMax, &yMin, &yMax, segment.xStart(), segment.yStart());
updateRange(&xMin, &xMax, &yMin, &yMax, segment.xEnd(), segment.yEnd());
}
for (PlotStore::Rect rectangle : rects()) {
float x = rectangle.x();
float y = rectangle.y();
updateRange(&xMin, &xMax, &yMin, &yMax, x, y);
updateRange(&xMin, &xMax, &yMin, &yMax, x + rectangle.width(), y + rectangle.height());
}
checkPositiveRangeAndAddMargin(&xMin, &xMax);
checkPositiveRangeAndAddMargin(&yMin, &yMax);
setXMin(xMin);
setXMax(xMax);
setYMin(yMin);
setYMax(yMax);
}
}
}