[Matplotlib-devel] Backend for use with Qt/QML

Hallo List,

I need to embed matplotlib in a Qt5/QML application, and found a starting point created
by Frederic Collonval.
It is a fairly old version, and not working anymore, so I forked it to create an updated version.
It can be found on
     https://github.com/SietseAchterop/matplotlib_qtquick_playground
I only updated the backend and the QtQuick version 2 example.

But I am stuck in the backend, in backend_qquick5agg.py.
In the QtQuick.QQuickPaintedItem function paint in line 118 there is:
      stringBuffer = self.renderer._renderer.tostring_bgra()

Both tostring_xxx functions do not exist anymore. How can I solve this?
Is the byteorder problem solved somewhere else? Is this a qt4/qt5 issue?

Hopefully someone can point me in a direction. It would be very nice to have
a possibility to use matplotlib within QML apps.

    Thanks in advance,
        Sietse

···

_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@python.org
https://mail.python.org/mailman/listinfo/matplotlib-devel

Sietse,

The methods are only removed from the c++ classes (which is what you are accessing via _renderer) which we consider private and will change with no warning (see https://github.com/matplotlib/matplotlib/pull/11735 for the PR where this was done). It looks like there are still public methods with the same name on RendererAgg.

I also suggest having a look at how we are doing this in our qt5agg backend (https://github.com/matplotlib/matplotlib/blob/616d6729368e6f4997bb759b171051a2b9ad882c/lib/matplotlib/backends/backend_qt5agg.py#L61-L75). Is there a reason you can not directly use the QWidget sub-class we provide (https://github.com/matplotlib/matplotlib/blob/616d6729368e6f4997bb759b171051a2b9ad882c/lib/matplotlib/backends/backend_qt5agg.py#L17)?

Tom

···

Thomas Caswell
tcaswell@gmail.com

Thanks Tom for the response.

The methods are only removed from the c++ classes (which is what you are accessing via `_renderer`) which we consider private and will change with no warning (see Change {FigureCanvasAgg,RendererAgg}.buffer_rgba to return a memoryview. by anntzer · Pull Request #11735 · matplotlib/matplotlib · GitHub for the PR where this was done). It looks like there are still public methods with the same name on RendererAgg.

Yes, but not the tostring_bgra version. And it seems that matplotlib is in rgba byte order, so it needs this conversion when
the byteorder is little endian as with a regular PC. Or am I mistaken?

My patch, that works on my intel PC, is adding and using the following function

   def tostring_bgra(self):
       return np.asarray(self._renderer).take([2, 1, 0, 3], axis=2).tobytes()

To RendererAgg.
Maybe add this function to RendererAgg?

Is there a reason you can not directly use the QWidget sub-class we provide ?

Well, this is what the code I forked from did.
I think the reason is that to embed in a Qt/QML program and being able to paint directly on the canvas we need to subclass QtQuick.QQuickPaintedItem.
See
   Writing QML Extensions with C++ | Qt QML 5.15.16

QML is quite different than traditional Qt.

    Thanks again,
        Sietse

···

On 11/22/19 7:55 PM, Thomas Caswell wrote:
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@python.org
https://mail.python.org/mailman/listinfo/matplotlib-devel

Qt can directly plot from RGBA8888 data (matplotlib’s native byte order), per https://doc.qt.io/qt-5/qimage.html#Format-enum. (Yes, the docs mention that it is less optimized but that’s just a byteswap, performance-wise I would guess the cost is the same whether it is done on Python’s side or Qt’s). I guess the place you need to change in your code is https://github.com/SietseAchterop/matplotlib_qtquick_playground/blob/master/backend/backend_qtquick5/backend_qquick5agg.py#L130 (and similar).
Antony

···

On Sat, Nov 23, 2019 at 1:56 PM s.achterop@rug.nl s.achterop@rug.nl wrote:

On 11/22/19 7:55 PM, Thomas Caswell wrote:

Thanks Tom for the response.

The methods are only removed from the c++ classes (which is what you are accessing via _renderer) which we consider private and will change with no warning (see https://github.com/matplotlib/matplotlib/pull/11735 for the PR where this was done). It looks like there are still public methods with

the same name on RendererAgg.

Yes, but not the tostring_bgra version. And it seems that matplotlib is in rgba byte order, so it needs this conversion when

the byteorder is little endian as with a regular PC. Or am I mistaken?

My patch, that works on my intel PC, is adding and using the following function

def tostring_bgra(self):

   return np.asarray(self._renderer).take([2, 1, 0, 3], axis=2).tobytes()

To RendererAgg.

Maybe add this function to RendererAgg?

Is there a reason you can not directly use the QWidget sub-class we provide ?

Well, this is what the code I forked from did.

I think the reason is that to embed in a Qt/QML program and being able to paint directly on the canvas we need to subclass QtQuick.QQuickPaintedItem.

See

https://doc.qt.io/qt-5/qtqml-tutorials-extending-qml-example.html

QML is quite different than traditional Qt.

Thanks again,

    Sietse

Matplotlib-devel mailing list

Matplotlib-devel@python.org

https://mail.python.org/mailman/listinfo/matplotlib-devel

Thanks Antony.
I changed Qt image format to RGBA888 and now do simply
    stringBuffer = np.asarray(self.renderer._renderer).tobytes()

Still am a bit confused about the endian test, but I will find out when I port
it to ARM for my android tablet.
   Thanks,
      Sietse

···

On 23-11-19 19:48, Antony Lee wrote:

Qt can directly plot from RGBA8888 data (matplotlib's native byte order), per QImage Class | Qt GUI 5.15.16. (Yes, the docs mention that it is less optimized but that's just a byteswap, performance-wise I would guess the cost is the same whether it is done on Python's side or Qt's). I guess the place you need to change in your code is https://github.com/SietseAchterop/matplotlib_qtquick_playground/blob/master/backend/backend_qtquick5/backend_qquick5agg.py#L130 (and similar).

_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@python.org
https://mail.python.org/mailman/listinfo/matplotlib-devel