QCustomPlot Discussion and Comments

QCPGraph/Curve with varying color ?Return to overview

Hi,
I'd need to draw a line (QCPGraph or QCPCurve) with the color of each "point" of the line depending on a value associated to this point.

Said otherwise, for each (x,y) point on my curve I have a value (z) that define the color of that point, and some sort of "color interpolation" between points (like a QCPColorGradient).

Said otherwise, I have points (x,y,z) in 3d space and I want to plot them in the XY plane with the z info encoded in the color.

Any way to do this ?

Thanks !

QPen has the method setBrush(QBrush); http://doc.qt.io/qt-5/qpen.html#setBrush
QBrush has a constructor that takes a gradient as a parameter http://doc.qt.io/qt-5/qbrush.html#QBrush-9

QLinearGradient lGrad(QPointF(0,0), QPointF(0,500));
lGrad.setColorAt(0, QColor(Qt::red));
lGrad.setColorAt(1, QColor(Qt::green));
QBrush lBrush(lGrad);
myPen.setBrush(lBrush);

myGraph->setPen(myPen);

You still need to calculate the "start", "final" points, and intermediate points for the linear gradient. (In the coordinate system of the device - QWidget)

Carefully re-read your post and realized that I advised not quite what you need)

If the grid formed by a set of points (x, y) is regular, then perhaps QCPColorMap will suit you

Thanks define true false, but that won't help, as you noticed.

Even in Matlab this doesn't seem to be trivial, see https://stackoverflow.com/questions/31685078/change-color-of-2d-plot-line-depending-on-3rd-value

Nobody ?

I'd like to do somethink like this : https://i.imgur.com/MLAEuad.png

OK, I'll assume it's not doable today with qCustomPlot. I'll repost as a request. Thx !

Has been on my feature request list for quite some time, but an elegant integration into the current QCPGraph is not trivial, so I've delayed it a few times.

I always have to keep users in mind who need maximum performance though, and adding this additional color value coordinate to each data point would be a too significant hit in speed and memory consumption (it would increase the size by 50%). Once I have found a way to properly handle those two cases elegantly, I'll definitely implement it.

I haven't tried the approach of setting QLinearGradient to the QBrush/Pen, but I've done something just like the image you posted by simply making a subclass of QCPGraph and overriding the drawLinePlot method. In that method (which you can mostly copy from QCPGraph), set the pen for each segment according to some value from a QCPColorGradient. Works fine for me and my use case, but maybe not the most efficient way to do it.

E.g., insert something like:

QColor color = mGradient.color(i, QCPRange(0, lineDataSize));
QPen pen;
pen.setColor(color);
// Maybe change other aspects of the pen...
painter->setPen(pen);

into the loop that draws each segment of the graph. Here mGradient would be some preset QCPColorGradient.

Thx for the answers.

I had a quick look at the code (and asked around on a Qt mailing list) and got similar answers.

Understood that performance & memory penalties may not allow to integrate this in QCPGraph/QCPCurve (plus other stuff like, what do one use as line color in a legend for such a line ?). But yeah, creating a dedicted plot type could avoid that, no ?

I may use this in a little telemetry viewer app that displays graphs of telemetry data collected by cars/bikes/karts simulators. The idea is to plot a variable (e.g. throttle position or speed) against the <x,y> position on the track.

the way i've seen it done in other graphics program is you store a list of gradient points in the graph and then when drawing it, you just look up what color it is supposed to be based on the gradient.

so lets say you wanted a line graph that was green at 0 and red at 100, you would store points (0,"green") and (100,"red") in the graph and then a function would do a linear interpolation between the two points to get the color you want and then use this to look up the value.

This adds extra processing time, but it wouldnt add much extra size (just a few values per graph instead of per point).

Ian, in this case you're right and QCPColorGradient already does all that interpolating. But in this way the color is deduced from the normal value (y coordinate) of the data points and thus only a bit of visual sugar.

What most people want though, is to display a new, separate data dimension in the form of color. So one line segment going through x=1,y=2 will be blue and the other segment at x=5,y=2 will be red, because a third dimension ("y2" so to say) is a value that maps to blue and red at the respective points. This necessitates the extra data storage and handling in QCPGraphData/QCPGraph.

Just to confirm what DeManu just wrote, need is for a color based on a third dimension.

What if you had say 10 diferent colors, you could have 10 graphs. Each with one color. Each time you wanted to plot a diferent color you could have a value for that graph and NaN for every other graph.
Z axis would have only 10 discrete values.

Not very elegant though.