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

Fixed in next patch/minor release.

The qFuzzyIsNull was correct, but it should check the pixel values, not plot coordinates (so keyPx instead of key, prevKeyPx instead of prevKey, valuePx instead of value, prevValuePx instead of prevValue).

Thanks for reporting!