Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[ENH]: Add a QtPgfPng backend? #28086

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
anntzer opened this issue Apr 16, 2024 · 9 comments
Open

[ENH]: Add a QtPgfPng backend? #28086

anntzer opened this issue Apr 16, 2024 · 9 comments
Labels
backend: pgf New feature status: has patch patch suggested, PR still needed
Milestone

Comments

@anntzer
Copy link
Contributor

anntzer commented Apr 16, 2024

Problem

Per #28084 and a few other older similar issues, some users are confused because they cannot see pgf-generated plots (which can include xelatex/lualatex-specific latex constructs, in particular) interactively, as the interactive guis still use the "standard" latex support.

As it turns out it is relatively easy(?) to implement a minimal "interactive" backend that uses pgf and pdf->png to conversion to interactively display pgf-generated plots. Obviously it has the most terrible performance ever (each draw involves a full tex compilation of the image), but (per the above) it could have some uses...

Proposed solution

Minimum patch implementing the (minimally tested...) backend is below. Test e.g. by setting MPLBACKEND to qtpgfpng and plotting.

diff --git c/lib/matplotlib/backends/backend_qtpgfpng.py i/lib/matplotlib/backends/backend_qtpgfpng.py
new file mode 100644
index 0000000000..f44097dc0b
--- /dev/null
+++ i/lib/matplotlib/backends/backend_qtpgfpng.py
@@ -0,0 +1,27 @@
+from tempfile import TemporaryDirectory
+
+import numpy as np
+import PIL.Image
+
+from .backend_pgf import FigureCanvasPgf
+from .backend_qt import FigureCanvasQT
+from .qt_compat import QtGui
+
+
+class FigureCanvasQTPgfPng(FigureCanvasPgf, FigureCanvasQT):
+    def paintEvent(self, event):
+        with TemporaryDirectory() as tmpdir:
+            self.print_png(f"{tmpdir}/image.png")
+            img = np.asarray(PIL.Image.open(f"{tmpdir}/image.png"))
+        qimage = QtGui.QImage(
+            img, img.shape[1], img.shape[0],
+            QtGui.QImage.Format.Format_RGBA8888)
+        qimage.setDevicePixelRatio(self.device_pixel_ratio)
+        painter = QtGui.QPainter(self)
+        painter.eraseRect(event.rect())
+        painter.drawImage(0, 0, qimage)
+        self._draw_rect_callback(painter)
+        painter.end()
+
+
+FigureCanvas = FigureCanvasQTPgfPng
diff --git c/lib/matplotlib/backends/meson.build i/lib/matplotlib/backends/meson.build
index 1e3e47c0a9..967cab902b 100644
--- c/lib/matplotlib/backends/meson.build
+++ i/lib/matplotlib/backends/meson.build
@@ -19,6 +19,7 @@ python_sources = [
   'backend_qt.py',
   'backend_qtagg.py',
   'backend_qtcairo.py',
+  'backend_qtpgfpng.py',
   'backend_qt5.py',
   'backend_qt5agg.py',
   'backend_qt5cairo.py',
diff --git c/lib/matplotlib/backends/registry.py i/lib/matplotlib/backends/registry.py
index 484d6ed5f2..ac18cc28c9 100644
--- c/lib/matplotlib/backends/registry.py
+++ i/lib/matplotlib/backends/registry.py
@@ -32,7 +32,7 @@ class BackendRegistry:
         "GTK3Agg", "GTK3Cairo", "GTK4Agg", "GTK4Cairo",
         "MacOSX",
         "nbAgg",
-        "QtAgg", "QtCairo", "Qt5Agg", "Qt5Cairo",
+        "QtAgg", "QtCairo", "QtPgfPng", "Qt5Agg", "Qt5Cairo",
         "TkAgg", "TkCairo",
         "WebAgg",
         "WX", "WXAgg", "WXCairo",

(#27913 (comment) is also relevant)

@tacaswell tacaswell added this to the v3.10.0 milestone Apr 16, 2024
@tacaswell tacaswell added the status: has patch patch suggested, PR still needed label Apr 16, 2024
@tacaswell
Copy link
Member

Seems reasonable. It looks like a majority of the work left writing a lot of docs?

@anntzer
Copy link
Contributor Author

anntzer commented Apr 16, 2024

Yes (including explaining in what context that would be useful). Perhaps also set whatever attributes are needed to mark this as not supporting blitting. Also decide whether we also want the same for the other GUI toolkits (it's just busy work I suspect...).

@jklymak
Copy link
Member

jklymak commented Apr 16, 2024

I'm not following why this is a desirable feature?

@tacaswell
Copy link
Member

Interactive figures are great for exploration or fine tuning (a semi-common workflow for me is to work in an IPython shell using the explicit API to poke at a live figure and then doing %history and copy-pasting-editing that to save). Making this "just work", even with a super slow render, for people who want to output to pgf is small win (now I guess you could do fig.savefig(...) and hope your pdf viewer out-refreshes).

@jklymak
Copy link
Member

jklymak commented Apr 16, 2024

Fair, I just think the point of PGF is to write the plot in the PGF language for including in a (**)TeX document, so creating a very slow viewer for the compiled result seems out of scope. I appreciate that the code cost is low, but my concern is that it raises expectations and obscures the point of the PGF backend.

@tacaswell
Copy link
Member

This only uses public API, maybe the right path is to put this in a new very thin repo and see if it gets any usage?

@jklymak
Copy link
Member

jklymak commented Apr 16, 2024

Sounds possible, or even as an example.

BTW I'm not strongly opposed at all, just making sure we aren't adding a feature that we will later regret.

@anntzer
Copy link
Contributor Author

anntzer commented Apr 16, 2024

I don't really mind either way; the main question is how to best help users confused by what parts support xelatex syntax and what parts don't (#5234, #28084).

@ArchangeGabriel
Copy link
Contributor

Yes please, ever since #5234 indeed I have to workaround the fact interactive display is using latex and not the pgf engine (used to be xelatex at that time, but I’ve long switched to lualatex). So I would very much welcome such a backend. :)

@timhoffm timhoffm modified the milestones: v3.10.0, v3.11.0 Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend: pgf New feature status: has patch patch suggested, PR still needed
Projects
None yet
Development

No branches or pull requests

5 participants