QCustomPlot Discussion and Comments

Graphical artifacts on QCPCurve for very small valuesReturn to overview

Hi,

I am hitting a graphical bug in my plot, which I think is caused by the optimization algorithm of QCPCurve. When a point of the curve goes off screen, some unrelated lines can appear, starting from the intersection of the line and the axis. The bug happens when the values I plot are very small.

It is easy to reproduce it in version 2.0, with the keys {1, 2, 3} and the values {6e-20, 4e-20, 5e-20}.

I looked at the optimization code, and I see that qFuzzyIsNull is used in a few places. The Qt doc says that qFuzzyIsNull considers a double to be null if it is less than 1e-12. Indeed, if I use the values {6e-13, 4e-13, 5e-13} the noisy lines appear, but if I use the values {6e-11, 4e-11, 5e-11} everything works well.

Is this a known limitation of QCustomPlot? These small values are real physical quantities that I need to plot (and they need to be plotted on a QCPCurve). Can you recommend a way to work around this issue?

I replaced the two calls to `qFuzzyIsNull` by a simple `==` comparison, in the method QCPCurve::getTraverse. This change removes the graphical bug I was having.

diff --git a/qcustomplot.cpp b/qcustomplot.cpp
--- a/qcustomplot.cpp
+++ b/qcustomplot.cpp
@@ -22855,12 +22855,12 @@ bool QCPCurve::getTraverse(double prevKe
   const double valuePx = mValueAxis->coordToPixel(value);
   const double prevKeyPx = mKeyAxis->coordToPixel(prevKey);
   const double prevValuePx = mValueAxis->coordToPixel(prevValue);
-  if (qFuzzyIsNull(key-prevKey)) // line is parallel to value axis
+  if (key == prevKey) // line is parallel to value axis
   {
     // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 is traversed here
     intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyPx, valueMinPx) : QPointF(valueMinPx, keyPx)); // direction will be taken care of at end of method
     intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyPx, valueMaxPx) : QPointF(valueMaxPx, keyPx));
-  } else if (qFuzzyIsNull(value-prevValue)) // line is parallel to key axis
+  } else if (value == prevValue) // line is parallel to key axis
   {
     // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 is traversed here
     intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMinPx, valuePx) : QPointF(valuePx, keyMinPx)); // direction will be taken care of at end of method