QCustomPlot Discussion and Comments

Support for retina display Macs?Return to overview


Thanks for a beautiful plotting framework! It's part of the weather station software I have running in my house. I was wondering, though, I can't seem to find a way to get it to draw in high resolution on my MacBook's retina display. Pretty much everything else in the app does draw at high res, though. I've looked around on the web and not found any easy fixes.

Any help on this would be appreciated.

Your application could detect a high DPI of the screen and then adapt the line thicknesses, font sizes, paddings etc. of QCustomPlot accordingly. Note that this will slow down things as thick-line drawing is generally a slower process. To achieve sharp pixel lines on screens, QCustomPlot is pixel-based and not mm/inch based, so it doesn't compensate for DPI.

Thanks for the reply! The rest of my app does draw in high DPI mode (fonts, controls)...I guess I'll have to figure out how it detects this and could send that along to QCustomPlot.

Any success on this? My qcustomplots look pixelated relative to the rest of my app.

I'm also looking for this.

I think the problem is that QCustomplot draws into intermediate pixmaps which are not scaled to match the physical device. For example, changing QCustomPlot::resizeEvent to the following fixes the main graph:

void QCustomPlot::resizeEvent(QResizeEvent *event)
  // resize and repaint the buffer:
  QSize pbSize = event->size();
  pbSize *= devicePixelRatio();
  mPaintBuffer = QPixmap(pbSize);
  replot(rpQueued); // queued update is important here, to prevent painting issues in some contexts

Hi Gerald, that's a good idea for QCP version 2.0!
I'll have to find out whether this breaks on some systems with strange devicePixelRatio, but it's definitely a much cleaner way to realize DPI-flexible plots without doing it manually.
For backward compatibility reasons it won't be introduced before version 2.0 though.

Thanks! After a bit of reading I wonder if it would be a good idea to get rid of mPaintBuffer altogether. It looks like drawing to QPixmap discards sub-pixel antialiasing, e.g. ClearType. I have no idea how feasible that would be in QCP's case, however.

To get its performance, QCustomPlot uses pixmap caching of expensive objects in the plot, especially texts. So even if I got rid of the overall paint buffer, there are still individual QPixmaps around for caching. Up to Qt 4.8 this was great, because QPixmap was a device pixmap and supported sub-pixel antialiasing, all was great. Then the Qt devs decided to change that and haven't fixed it since:
Very unfortunate for all widgets out there that need to do expensive painting and would like to (or have to) cache some of that in pixmaps :/.

The reason to have a paint buffer pixmap in the paint event and only draw the scene on that is to avoid flicker for Qt 4.6 and Qt 4.7 (http://doc.qt.digia.com/qq/qq06-flicker-free.html). Back in the time, QWidget painters would directly show the drawn lines, and not perform double buffering automatically in their ::end() call. So one had to take care of that, which, since QPixmaps supported sub-pixel antialiasing, wasn't a big deal.

Anyway, I'll check out whether removing (conditionally for Qt >= 4.8) the explicit double-buffering improves anything. At least, it would give sub-pixel antialiasing of texts if text caching is disabled (QCustomPlot::setPlottingHint(QCP::phCacheLabels, false)), at the expense of performance.

Running QCP on mobile and having the same issues. It isn't the end of the world, just looks a little funny.

@ Gerald, That resize code just makes the QPixmap 2x bigger. Is there code elsewhere that would make the size scale with the resolution?

In response to my previous comment, I got that code working (my issue was that I had also changed the `paintEvent()`), but just changing the paint buffer size and setting the device pixel ratio makes a huge performance difference for the worse.

Did anyone succeed in retina plotting with QT4? In principle it should be possible to just draw in larger pixmaps and get the scaling factor from NSView.