Skip to content

Draw thin curves with a cosmetic pen on screen (fast rendering on HiDPI screens) - #81

Merged
PierreRaybaut merged 1 commit into
developfrom
feature/80-cosmetic-curve-pen
Oct 29, 2026
Merged

PierreRaybaut merged 1 commit into
developfrom
feature/80-cosmetic-curve-pen

Conversation

@PierreRaybaut

Copy link
Copy Markdown
Contributor

Closes #80. Part of DataLab-Platform/DataLab#453 (curve readability).

Problem

With a display scaling factor such as 125 % or 150 %, a curve of width 1.0 is drawn wider than one device pixel, and Qt's raster engine takes its slow path for wide pens. Noisy curves become several hundred times slower to draw.

Change

  • CurveItem.drawCurve (and the error bars of ErrorBarCurveItem) draws thin pens with a cosmetic copy of the pen, i.e. one device pixel wide, through the new get_screen_pen() helper.
  • This only applies on screen: raster paint engine without scaling transform. Printing and exporting (PDF/printer engines, or the scaled painter of QwtPlotRenderer) are not affected.
  • The stored pen and the curve parameters (LineStyleParam.width) are unchanged.
  • The new curve/cosmetic_hairline option of the plot configuration section (enabled by default) restores the previous behavior.

Measurements

Noisy curve, 2000 points, antialiased, CurveItem.drawSeries on a QImage:

Device pixel ratio Option disabled Option enabled
1.0 2.8 ms 2.5 ms
1.5 598 ms 3.6 ms

Tests

New plotpy/tests/unit/test_curve_screen_pen.py:

  • thin and wide pens;
  • other paint engines and scaled painters;
  • configuration option;
  • pixel-level rendering at device pixel ratio 2 (curves and error bars);
  • stored parameters unchanged.

The plotpy/tests/unit and plotpy/tests/items suites pass locally, except test_edit_point_tool, which also fails locally without this change (mouse simulation).

With a display scaling factor such as 150 %, curves and error bars of
width 1 were drawn wider than one device pixel, which made Qt's raster
engine take its slow path for wide pens (about 800 ms instead of 3 ms
for a noisy 2000-point curve).

When painting on screen (raster engine without scaling transform), pens
of width 1 or less are now made cosmetic at drawing time. The stored pen
and curve parameters are unchanged, and printing or exporting (other
paint engines or scaled painters) is not affected. The new
`curve/cosmetic_hairline` option of the `plot` section restores the
previous behavior.

Closes #80

Assisted-by: Claude Opus 5.5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant