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

Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

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

s.achterop@rug.nl
     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
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-devel
Reply | Threaded
Open this post in threaded view
|

Re: Backend for use with Qt/QML

tcaswell
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.


Tom

On Thu, Nov 21, 2019 at 8:48 AM [hidden email] <[hidden email]> wrote:
     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
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-devel


--
Thomas Caswell
[hidden email]

_______________________________________________
Matplotlib-devel mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-devel
Reply | Threaded
Open this post in threaded view
|

Re: Backend for use with Qt/QML

s.achterop@rug.nl
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
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-devel
Reply | Threaded
Open this post in threaded view
|

Re: Backend for use with Qt/QML

Antony Lee-3
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 [hidden email] <[hidden email]> 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
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-devel

_______________________________________________
Matplotlib-devel mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-devel
Reply | Threaded
Open this post in threaded view
|

Re: Backend for use with Qt/QML

s.achterop@rug.nl
On 23-11-19 19:48, Antony Lee wrote:
> 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).

   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
_______________________________________________
Matplotlib-devel mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-devel