fast plotting in wx

For anyone interested, I just stripped down the older wxPyPlot by K.Hinsen to speed up the Draw methods and got a 3-5x increase over wyPyPlot, which was ~50% faster than wx.lib.plot.

All axis, labels, grid etc are stripped out, and the scales must be specified:
client.Draw(drawObj, xAxis= (0,5), yAxis= (0,10)).
The presumption is that you draw the axes outside the canvas area, or don't want any - there's now no dynamic scaling. Otherwise all calls are the same so it can drop in.
Depends on numpy.
Upgraded the code to wx2.8.
I also pared down the example __test(), if you run it.
Boa plug-in attached as well.

-Ray

wxPlotter.py (29.1 KB)

wxPlotter.plug-in.py (1.86 KB)

RayS wrote:

For anyone interested, I just stripped down the older wxPyPlot by K.Hinsen to speed up the Draw methods and got a 3-5x increase over wyPyPlot, which was ~50% faster than wx.lib.plot.

All axis, labels, grid etc are stripped out, and the scales must be specified:
client.Draw(drawObj, xAxis= (0,5), yAxis= (0,10)).
The presumption is that you draw the axes outside the canvas area, or don't want any - there's now no dynamic scaling. Otherwise all calls are the same so it can drop in.
Depends on numpy.
Upgraded the code to wx2.8.
I also pared down the example __test(), if you run it.
Boa plug-in attached as well.

Would it make sense to refactor wx.lib.plot to use your module for drawing the plot and still do the axes, scaling, panning, zooming, etc. itself? That way people could have a choice to use either the full plotting features, or just the simpler and faster plot with no decorations, bells or whistles.

BTW, on Mac it's an error to try and create a bitmap that has zero dimensions, so you should change the creation of the buffer to be like this:

         self._Buffer = wx.EmptyBitmap(max(1,Size[0]), max(1,Size[1]))

···

--
Robin Dunn
Software Craftsman

RayS wrote:
> For anyone interested, I just stripped down the older wxPyPlot by K.Hinsen
> to speed up the Draw methods and got a 3-5x increase over wyPyPlot, which
> was ~50% faster than wx.lib.plot.
>
> All axis, labels, grid etc are stripped out, and the scales must be specified:
> client.Draw(drawObj, xAxis= (0,5), yAxis= (0,10)).
> The presumption is that you draw the axes outside the canvas area, or don't
> want any - there's now no dynamic scaling. Otherwise all calls are the same
> so it can drop in.
> Depends on numpy.
> Upgraded the code to wx2.8.
> I also pared down the example __test(), if you run it.
> Boa plug-in attached as well.

Would it make sense to refactor wx.lib.plot to use your module for
drawing the plot and still do the axes, scaling, panning, zooming, etc.
itself? That way people could have a choice to use either the full
plotting features, or just the simpler and faster plot with no
decorations, bells or whistles.

Adding a method like PlotCanvas.DrawFast() might be nice. I do like the power of lib.plot but in the past I've written numerous small methods to draw data directly to DCs to get speed back. Stripping down Draw() is a good compromise.
Adding a whole class like FastPlotCanvas might make sense too, as many of the methods could be dropped or stubbed out.

Most of what I'd concentrated on was PlotCanvas.Draw() with some minor mods to PolyLine and PolyPoints Classes. Most of the rest was simply stripping out superfluous code for the print,save etc as well as anything to do with fonts and legends. Not guaranteed complete as some of the rectangle/range stuff could go too.
I tried to put the numpy array creation lines into __init__ so they don't need to be run with every Draw, but didn't quite get there. They probably cost a few cycles and since the plot size cannot change they could be done in init. The only Draw() aspect that can be optimized further is the graphics.scaleAndShift(scale, shift) call which eats about half of the remaining time. I tried pushing it to the init and adding scale to the init call, but then would need to re-think OnSize().

BTW, on Mac it's an error to try and create a bitmap that has zero
dimensions, so you should change the creation of the buffer to be like this:

         self._Buffer = wx.EmptyBitmap(max(1,Size[0]), max(1,Size[1]))

I guess it was that a known issue with wxPyPlot as well? I see that lib.plot fixed it.

In the attached I added the ability to pass a bitmap to PlotCanvas which then saves a copy and resizes the bmp to the client as needed. Not quite sure why I can't just set self._Buffer = self.bmp...
In any case, that is the way I set up complex backgrounds for other plots (like polar) before drawing, and it then requires the extra PlotCanvas borderSize arg to scale the data to the bg.
The alternative is to set borderSize=0. and place the plotCanvas on top of a staticBitmap, or a canvas with labels etc. The original bitmap should be sized to the largest expected to look best.

-Ray

wxPlotter.py (23.9 KB)

···

At 09:11 AM 7/22/2009 -0700, you wrote: