First cut on a QtAgg backend

  * The only explanation I can think of for why the colors

    > are wrong is that qt has a different byte order for images
    > than you are getting from agg (is could it be bgra instead
    > of rgba, or that something is wrong with the endianess...)
    > If you need a different byte ordering /pixel format, I can
    > provide the required method in the agg backend. I note that
    > the saved figures *do* have the right color scheme, which
    > supports this idea.

Another clue that endianess is playing a role here is that the colors
are dramatically different on OSX (which I tested yesterday) ans linux
which I tested today. But I think it's more than an endian problem,
because the colors are wrong on both platforms. On linux, it looks
like the endianess is right, but it's an rgb versus bgr thing, since
the colors are backwards on

    from pylab import *
    subplot(211)
    plot([1,2,3], color='red')

    subplot(212)
    plot([1,2,3], color='blue')

    show()

On OSX, it looks like the endianess is wrong because the colors are
really off...

Also, I took a quick at the qimage class docs at
http://doc.trolltech.com/3.3/qimage.html and saw

It is one of the two classes Qt provides for dealing with images, the
other being QPixmap. QImage is designed and optimized for I/O and for
direct pixel access/manipulation. QPixmap is designed and optimized
for drawing. There are (slow) functions to convert between QImage and
QPixmap: QPixmap::convertToImage() and QPixmap::convertFromImage().

Does this suggest that QPixmap might be more appropriate / faster
since you don't need to do the individual pixel manipulation provided
by QImage (spoken as a total qt newbie, so please forgive any
stupidities on my part...)

An unrelated observation regarding event handling: the qt backend is
not connecting to mouse motion unless a pan/zoom button is pressed and
released, eg coords_demo.py does not work properly.

Cheers!
JDH

We've also been working on a Qt front end. It's been going slow because we've only been able to spend about 1 oerson-day per week on it. But, starting this week I have someone full time on it. He's gotten a basic widget working using the same organization that the GTK code uses. Sigve's code has a lot more functionality in the tool bars than ours right now.

Here's where we're at:
- Finished C++ routine to convert AGG -> QPixmap (in /src/_qtagg.cpp)
- Finished low level widget to display the AGG pixmap using a widget derived from QLabel (in ./lib/matplotlib/backends/backend_qtagg.py)
- Working on a higher level window widget to display the plot and the tool bar. We implemented the tool bar as a Qt tool bar which allows you drag it around, detach it, etc.

The guy working on it doesn't think it would take more than a day or two to incorporate Sigve's code for the tool bar handling into our code. We're close enough to finishing that it probably doesn't make a lot of sense to try and set up a collaboration right now but I'm open to that possibility if that's what people want. All I really interested in is seeing the QtAgg front end in matplotlib as a supported component (which we'd be happy to help maintain) so whatever gets us there the quickest sounds good to me.

Ted

PS: here's the code we used to do the AGG->QPixmap conversion. It may not be the fastest way to do it but it does work which is all we were after for the first cut.

PyQObject* pyDrawable = static_cast< PyQObject* >( args[0].ptr() );
QLabel* label = static_cast< QLabel* >( pyDrawable->obj );

RendererAgg* aggRenderer = static_cast< RendererAgg* >( args[1].ptr() );

unsigned int width = aggRenderer->get_width();
unsigned int height = aggRenderer->get_height();

QImage image( aggRenderer->pixBuffer, width, height, 32, 0, 256,
               QImage::LittleEndian );
QPixmap pixmap;
pixmap.convertFromImage( image, QPixmap::Color );

label->setPixmap( pixmap );

···

At 07:25 AM 1/31/2005, John Hunter wrote:

    > * The only explanation I can think of for why the colors
    > are wrong is that qt has a different byte order for images
    > than you are getting from agg (is could it be bgra instead
    > of rgba, or that something is wrong with the endianess...)
    > If you need a different byte ordering /pixel format, I can
    > provide the required method in the agg backend. I note that
    > the saved figures *do* have the right color scheme, which
    > supports this idea.

Another clue that endianess is playing a role here is that the colors
are dramatically different on OSX (which I tested yesterday) ans linux
which I tested today. But I think it's more than an endian problem,
because the colors are wrong on both platforms. On linux, it looks
like the endianess is right, but it's an rgb versus bgr thing, since
the colors are backwards on

    from pylab import *
    subplot(211)
    plot([1,2,3], color='red')

    subplot(212)
    plot([1,2,3], color='blue')

    show()

On OSX, it looks like the endianess is wrong because the colors are
really off...

Also, I took a quick at the qimage class docs at
http://doc.trolltech.com/3.3/qimage.html and saw

It is one of the two classes Qt provides for dealing with images, the
other being QPixmap. QImage is designed and optimized for I/O and for
direct pixel access/manipulation. QPixmap is designed and optimized
for drawing. There are (slow) functions to convert between QImage and
QPixmap: QPixmap::convertToImage() and QPixmap::convertFromImage().

Does this suggest that QPixmap might be more appropriate / faster
since you don't need to do the individual pixel manipulation provided
by QImage (spoken as a total qt newbie, so please forgive any
stupidities on my part...)

An unrelated observation regarding event handling: the qt backend is
not connecting to mouse motion unless a pan/zoom button is pressed and
released, eg coords_demo.py does not work properly.

Cheers!
JDH

-------------------------------------------------------
This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting
Tool for open source databases. Create drag-&-drop reports. Save time
by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc.
Download a FREE copy at http://www.intelliview.com/go/osdn_nl
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
matplotlib-devel List Signup and Options

Ted Drain Jet Propulsion Laboratory ted.drain@...179...

John Hunter wrote:

   > * The only explanation I can think of for why the colors
   > are wrong is that qt has a different byte order for images
   > than you are getting from agg (is could it be bgra instead
   > of rgba, or that something is wrong with the endianess...)
   > If you need a different byte ordering /pixel format, I can
   > provide the required method in the agg backend. I note that
   > the saved figures *do* have the right color scheme, which
   > supports this idea.

Another clue that endianess is playing a role here is that the colors
are dramatically different on OSX (which I tested yesterday) ans linux
which I tested today. But I think it's more than an endian problem,
because the colors are wrong on both platforms. On linux, it looks
like the endianess is right, but it's an rgb versus bgr thing, since
the colors are backwards on

   from pylab import *
   subplot(211)
   plot([1,2,3], color='red')

   subplot(212)
   plot([1,2,3], color='blue')

   show()

On OSX, it looks like the endianess is wrong because the colors are
really off...

This was actually wrong in windows also, read and blue had switched.

By using this draw, it is corrected.

    def draw(self):
        """
        Draw the figure using the renderer
        """
        FigureCanvasAgg.draw(self)
        self.stringBuffer = str(self.buffer_rgba())
        wrongqimage = qt.QImage(self.stringBuffer,
                            self.renderer.width,
                            self.renderer.height,
                            32,
                            None,
                            0,
                            qt.QImage.IgnoreEndian)
        self.qimage = wrongqimage.swapRGB()
        self.update()

That probably leaves us with the OSX problems, though. Ahh, fixed in CVS, ok then.

Also, I took a quick at the qimage class docs at
http://doc.trolltech.com/3.3/qimage.html and saw

It is one of the two classes Qt provides for dealing with images, the
other being QPixmap. QImage is designed and optimized for I/O and for
direct pixel access/manipulation. QPixmap is designed and optimized
for drawing. There are (slow) functions to convert between QImage and
QPixmap: QPixmap::convertToImage() and QPixmap::convertFromImage().

Does this suggest that QPixmap might be more appropriate / faster
since you don't need to do the individual pixel manipulation provided
by QImage (spoken as a total qt newbie, so please forgive any
stupidities on my part...)

I think that QPixmap or better yet QCanvas would be the appropriate if you are making a pure Qt-backend, but that QImage is the choice for a backend with other rendering as Agg or Cairo.

An unrelated observation regarding event handling: the qt backend is
not connecting to mouse motion unless a pan/zoom button is pressed and
released, eg coords_demo.py does not work properly.

Adding this to the end of FigureCanvasQtAgg.__init__ will fix tracking:

        self.setMouseTracking(True)

Regards,
Sigve

Hi again Ted,
As far as I can tell, we are using the same method to connect between Agg and Qt. You are doing it from C++, while I am doing it with python only. Another difference is that I subclass QWidget instead of QLabel. Can you please elaborate on why have you choosen QLabel over QWidget? I don�t see what QLabel gives you that you don�t have in QWidget. Perhaps you get double buffering? I am just curious and trying to learn� I don�t think there should be any major speed penalties by doing it all from python, but I haven�t benchmarked anything yet.

Please do incorporate whatever you need from my code into your version. I am not the right person to decide what should go into Matplotlib, any solution is fine by me. I am in the same position as you; I just want a Qt-backend for Matplotlib.

Good luck!

Best regards,
Sigve I

Ted Drain skrev:

···

We've also been working on a Qt front end. It's been going slow because we've only been able to spend about 1 oerson-day per week on it. But, starting this week I have someone full time on it. He's gotten a basic widget working using the same organization that the GTK code uses. Sigve's code has a lot more functionality in the tool bars than ours right now.

Here's where we're at:
- Finished C++ routine to convert AGG -> QPixmap (in /src/_qtagg.cpp)
- Finished low level widget to display the AGG pixmap using a widget derived from QLabel (in ./lib/matplotlib/backends/backend_qtagg.py)
- Working on a higher level window widget to display the plot and the tool bar. We implemented the tool bar as a Qt tool bar which allows you drag it around, detach it, etc.

The guy working on it doesn't think it would take more than a day or two to incorporate Sigve's code for the tool bar handling into our code. We're close enough to finishing that it probably doesn't make a lot of sense to try and set up a collaboration right now but I'm open to that possibility if that's what people want. All I really interested in is seeing the QtAgg front end in matplotlib as a supported component (which we'd be happy to help maintain) so whatever gets us there the quickest sounds good to me.

Ted

PS: here's the code we used to do the AGG->QPixmap conversion. It may not be the fastest way to do it but it does work which is all we were after for the first cut.

PyQObject* pyDrawable = static_cast< PyQObject* >( args[0].ptr() );
QLabel* label = static_cast< QLabel* >( pyDrawable->obj );

RendererAgg* aggRenderer = static_cast< RendererAgg* >( args[1].ptr() );

unsigned int width = aggRenderer->get_width();
unsigned int height = aggRenderer->get_height();

QImage image( aggRenderer->pixBuffer, width, height, 32, 0, 256,
QImage::LittleEndian );
QPixmap pixmap;
pixmap.convertFromImage( image, QPixmap::Color );

label->setPixmap( pixmap );