I think I actually got the new api working with
> draw_markers and draw_lines in backend_ps. The transforms
> are done by passing the results of transform.as_vec6_val
> to postscript. I would appreciate it if someone would test
> it out and give me feedback. In order to do so, update
> from svn and unmask backend_ps.RendererPS._draw_markers
> (not _draw_markers_old) by removing the leading
> underscore. Try plotting things like
I think the best way to get people to test this is to make it the
default in backend_ps -- then all svn users will be testing it
automatically and you will hear about it when there is a problem. They
don't call it "the bleeding edge" for nothing. I made this change in
svn, revision 2173.
> plot([0,1,2,3,4],'-o'); savefig('linear.eps')
> plot([0,1,nan,3,4],'-o'); savefig('linear_nan.eps') # Not
> possible with the old API semilogy([0,1,2,3,4],'-o');
> savefig('nonlinear.eps') semilogy([0,1,nan,3,4],'-o');
> savefig('nonlinear_nan.eps') # Not possible with the old
> API
> Are there other methods that need to be updated to use the
> new API? There are a bunch of unused methods in RendererPS
> that I will clean up once things have settled, please
> ignore them for now.
Just those two methods for now. I'd also like to add draw_paths and
remove many of the redundant ones.
Regarding a question from your previous post:
> Moving on, I've been trying to follow John's work in
> __draw_lines_hide (you masked that sucker twice, is it
> that bad?). Help me understand this, are we allowed to use
> transform.numerix_x_y in the new API, or do we have to use
> transform.as_vec6_val? If I can use the former:
You are certainly allowed to use it, and any other provided method,
but for nonlinear transformations it defeats the purpose of doing the
transformation in the backend. numerix_x_y transforms the entire
array with the affine plus nonlinear transform. If it fails on any
element the entire transformation fails. To prevent this problem you
would want to do an element wise transformation and on failures set
the path state for the next element to moveto, ie skip the bad point.
We have talked in the past about writing a helper routine to generate
the postscript path in extension code if performance becomes an issue.
I ran a test script to profile this before and after, making marker
plots of various sizes. I think you'll be happy with the fruits of
your labors. Because we save the effort of setting a gc for each
marker, and thus avoid of lot of redundant function calling and state
setting in the output file, the results are much better in time and space
import time, os
from pylab import figure, close, nx
for i in 10,100,1000,10000,100000:
fig = figure(1)
ax = fig.add_subplot(111)
x,y = nx.mlab.rand(2,i)
tnow = time.time()
ax.plot(x,y, 'o')
fname = 'file%d.ps'
fig.savefig(fname)
elapsed = time.time() - tnow
fsize = os.stat(fname)[6]
print 'i=%06d time= %1.2fs size=%1.1fkb'%(i, elapsed, fsize/1e3)
close(1)
Old API:
> python test.py
i=000010 time= 0.33s size=142.4kb
i=000100 time= 0.30s size=154.9kb
i=001000 time= 0.43s size=284.1kb
i=010000 time= 1.79s size=1575.9kb
i=100000 time= 15.37s size=14495.6kb
New API:
> python test.py
i=000010 time= 0.53s size=148.1kb
i=000100 time= 0.29s size=146.5kb
i=001000 time= 0.30s size=163.6kb
i=010000 time= 0.44s size=334.5kb
i=100000 time= 2.17s size=2044.5kb
So for largish marker plots, you have about a 7x improvement in speed
and filesize. You may want to use this script to profile and see if
you can't eke out some extra gains. Maybe another 2x <wink>. This is
using the default rc file.
Now that we have a good implementation in a pure python backend that
others can follow as an example, I will shortly deprecate the old API
entirely and begin pruning the redundant methods. Considering that
both your changes and Eric's are significant enhancements, we may wait
to do this until one release cycle down the road, so that we don't
delay getting these out to the wider community.
Thanks,
JDH