Skip to content

Commit 95aefc4

Browse files
authored
Merge pull request #21025 from QuLogic/cairo-hidpi
2 parents 01a9944 + 193d810 commit 95aefc4

8 files changed

+37
-7
lines changed

lib/matplotlib/backend_bases.py

+1
Original file line numberDiff line numberDiff line change
@@ -2257,6 +2257,7 @@ def print_figure(
22572257
# Remove the figure manager, if any, to avoid resizing the GUI widget.
22582258
with cbook._setattr_cm(self, manager=None), \
22592259
cbook._setattr_cm(self.figure, dpi=dpi), \
2260+
cbook._setattr_cm(canvas, _device_pixel_ratio=1), \
22602261
cbook._setattr_cm(canvas, _is_saving=True), \
22612262
ExitStack() as stack:
22622263

lib/matplotlib/backends/backend_cairo.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
245245

246246
ctx.save()
247247
ctx.select_font_face(*_cairo_font_args_from_font_prop(prop))
248-
ctx.set_font_size(prop.get_size_in_points() * self.dpi / 72)
248+
ctx.set_font_size(self.points_to_pixels(prop.get_size_in_points()))
249249
opts = cairo.FontOptions()
250250
opts.set_antialias(
251251
cairo.ANTIALIAS_DEFAULT if mpl.rcParams["text.antialiased"]
@@ -271,7 +271,7 @@ def _draw_mathtext(self, gc, x, y, s, prop, angle):
271271
ctx.move_to(ox, -oy)
272272
ctx.select_font_face(
273273
*_cairo_font_args_from_font_prop(ttfFontProperty(font)))
274-
ctx.set_font_size(fontsize * self.dpi / 72)
274+
ctx.set_font_size(self.points_to_pixels(fontsize))
275275
ctx.show_text(chr(idx))
276276

277277
for ox, oy, w, h in rects:
@@ -303,9 +303,7 @@ def get_text_width_height_descent(self, s, prop, ismath):
303303
# save/restore prevents the problem
304304
ctx.save()
305305
ctx.select_font_face(*_cairo_font_args_from_font_prop(prop))
306-
# Cairo (says it) uses 1/96 inch user space units, ref: cairo_gstate.c
307-
# but if /96.0 is used the font is too small
308-
ctx.set_font_size(prop.get_size_in_points() * self.dpi / 72)
306+
ctx.set_font_size(self.points_to_pixels(prop.get_size_in_points()))
309307

310308
y_bearing, w, h = ctx.text_extents(s)[1:4]
311309
ctx.restore()

lib/matplotlib/backends/backend_gtk3cairo.py

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ def on_draw_event(self, widget, ctx):
2828
allocation.width, allocation.height)
2929
self._renderer.set_width_height(
3030
allocation.width, allocation.height)
31+
self._renderer.dpi = self.figure.dpi
3132
self.figure.draw(self._renderer)
3233

3334

lib/matplotlib/backends/backend_gtk4cairo.py

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ def on_draw_event(self, widget, ctx):
2727
allocation.width, allocation.height)
2828
self._renderer.set_width_height(
2929
allocation.width, allocation.height)
30+
self._renderer.dpi = self.figure.dpi
3031
self.figure.draw(self._renderer)
3132

3233

lib/matplotlib/backends/backend_qtcairo.py

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ def __init__(self, figure=None):
1313

1414
def draw(self):
1515
if hasattr(self._renderer.gc, "ctx"):
16+
self._renderer.dpi = self.figure.dpi
1617
self.figure.draw(self._renderer)
1718
super().draw()
1819

@@ -23,6 +24,7 @@ def paintEvent(self, event):
2324
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
2425
self._renderer.set_ctx_from_surface(surface)
2526
self._renderer.set_width_height(width, height)
27+
self._renderer.dpi = self.figure.dpi
2628
self.figure.draw(self._renderer)
2729
buf = self._renderer.gc.ctx.get_target().get_data()
2830
if QT_API == "PyQt6":

lib/matplotlib/backends/backend_tkcairo.py

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ def draw(self):
1818
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
1919
self._renderer.set_ctx_from_surface(surface)
2020
self._renderer.set_width_height(width, height)
21+
self._renderer.dpi = self.figure.dpi
2122
self.figure.draw(self._renderer)
2223
buf = np.reshape(surface.get_data(), (height, width, 4))
2324
_backend_tk.blit(

lib/matplotlib/backends/backend_wxcairo.py

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def draw(self, drawDC=None):
3535
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
3636
self._renderer.set_ctx_from_surface(surface)
3737
self._renderer.set_width_height(width, height)
38+
self._renderer.dpi = self.figure.dpi
3839
self.figure.draw(self._renderer)
3940
self.bitmap = wxcairo.BitmapFromImageSurface(surface)
4041
self._isDrawn = True

lib/matplotlib/tests/test_figure.py

+27-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
from types import SimpleNamespace
77
import warnings
88

9+
import numpy as np
10+
import pytest
11+
from PIL import Image
12+
913
import matplotlib as mpl
1014
from matplotlib import cbook, rcParams
1115
from matplotlib._api.deprecation import MatplotlibDeprecationWarning
@@ -16,8 +20,6 @@
1620
import matplotlib.pyplot as plt
1721
import matplotlib.dates as mdates
1822
import matplotlib.gridspec as gridspec
19-
import numpy as np
20-
import pytest
2123

2224

2325
@image_comparison(['figure_align_labels'], extensions=['png', 'svg'],
@@ -496,6 +498,29 @@ def test_savefig_backend():
496498
fig.savefig("test.png", backend="pdf")
497499

498500

501+
@pytest.mark.parametrize('backend', [
502+
pytest.param('Agg', marks=[pytest.mark.backend('Agg')]),
503+
pytest.param('Cairo', marks=[pytest.mark.backend('Cairo')]),
504+
])
505+
def test_savefig_pixel_ratio(backend):
506+
fig, ax = plt.subplots()
507+
ax.plot([1, 2, 3])
508+
with io.BytesIO() as buf:
509+
fig.savefig(buf, format='png')
510+
ratio1 = Image.open(buf)
511+
ratio1.load()
512+
513+
fig, ax = plt.subplots()
514+
ax.plot([1, 2, 3])
515+
fig.canvas._set_device_pixel_ratio(2)
516+
with io.BytesIO() as buf:
517+
fig.savefig(buf, format='png')
518+
ratio2 = Image.open(buf)
519+
ratio2.load()
520+
521+
assert ratio1 == ratio2
522+
523+
499524
def test_figure_repr():
500525
fig = plt.figure(figsize=(10, 20), dpi=10)
501526
assert repr(fig) == "<Figure size 100x200 with 0 Axes>"

0 commit comments

Comments
 (0)