Merge lp:~kolmis/cairoplot/speedup into lp:cairoplot

Proposed by Karel Kolman
Status: Merged
Merged at revision: 41
Proposed branch: lp:~kolmis/cairoplot/speedup
Merge into: lp:cairoplot
Diff against target: 161 lines
4 files modified
trunk/cairoplot.py (+15/-6)
trunk/seriestests.py (+21/-7)
trunk/testscripts/compare.sh (+22/-0)
trunk/testscripts/timeit.sh (+3/-0)
To merge this branch: bzr merge lp:~kolmis/cairoplot/speedup
Reviewer Review Type Date Requested Status
Rodrigo Moreira Araújo Pending
Review via email: mp+12980@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Karel Kolman (kolmis) wrote :

Hi, i'm experimenting with using cairoplot to render plots in the wxbanker project and i stumbled upon some performance related problems which lead me to examining cairoplot's code. Summary of changes proposed in this branch:

 - speed up x_labels rendering
 +++ (create the rotation matrix once only, apply it for each x_label - this is a major improvement)

 - added a timer.sh script and a test plot with 1000 x_labels to show the performance difference

 - replace rotate(angle), rotate(-angle) pairs with save(), rotate(angle), restore() triples
 +++ (i have absolutely none experience in graphics programming, but i think this is the way to go, since i'd say these two rotations added don't have to result in an identity matrix due to floating number arithmetics and rounding errors)

 - added a script for visual comparison of outputs, it diffs two outputs from seriestests.py and creates diff images in PPM format
 +++ i performed the following test: i created two cairoplot versions:
 ====== 1. all show_text() references removed, the rotate(angle), rotate(-angle) statements stayed
 ====== 2. all show_text() references removed, all rotate() pairs removed
 ====== comparing these two some plots were different whereas they should be exactly the same

Revision history for this message
Karel Kolman (kolmis) wrote :

and i meant a minor improvement, not major :)

Revision history for this message
Rodrigo Moreira Araújo (alf-rodrigo) wrote :

Hello Karel,

I'm sorry for the long time, but I'd like to let you know I just merged your
code onto the main branch.

Thanks a lot for the contribution.

Cheers,

Rodrigo Araujo

On Wed, Oct 7, 2009 at 7:07 AM, Karel Kolman <email address hidden> wrote:

> and i meant a minor improvement, not major :)
> --
> https://code.launchpad.net/~kolmis/cairoplot/speedup/+merge/12980
> You are requested to review the proposed merge of
> lp:~kolmis/cairoplot/speedup into lp:cairoplot.
>

Revision history for this message
Karel Kolman (kolmis) wrote :

Thanks for merging the branch.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'trunk/cairoplot.py'
--- trunk/cairoplot.py 2009-07-09 21:57:24 +0000
+++ trunk/cairoplot.py 2009-10-07 10:00:26 +0000
@@ -510,9 +510,10 @@
510 if self.titles[VERT]:510 if self.titles[VERT]:
511 title_width,title_height = cr.text_extents(self.titles[VERT])[2:4]511 title_width,title_height = cr.text_extents(self.titles[VERT])[2:4]
512 cr.move_to( self.dimensions[HORZ] - self.borders[HORZ] + title_height/2, self.dimensions[VERT]/2 - title_width/2)512 cr.move_to( self.dimensions[HORZ] - self.borders[HORZ] + title_height/2, self.dimensions[VERT]/2 - title_width/2)
513 cr.save()
513 cr.rotate( math.pi/2 )514 cr.rotate( math.pi/2 )
514 cr.show_text( self.titles[VERT] )515 cr.show_text( self.titles[VERT] )
515 cr.rotate( -math.pi/2 )516 cr.restore()
516 517
517 def render_grid(self):518 def render_grid(self):
518 cr = self.context519 cr = self.context
@@ -544,21 +545,29 @@
544 cr = self.context545 cr = self.context
545 step = float( self.plot_width ) / ( len( self.labels[HORZ] ) - 1 )546 step = float( self.plot_width ) / ( len( self.labels[HORZ] ) - 1 )
546 x = self.borders[HORZ]547 x = self.borders[HORZ]
548 y = self.dimensions[VERT] - self.borders[VERT] + 5
549
550 # store rotation matrix from the initial state
551 rotation_matrix = cr.get_matrix()
552 rotation_matrix.rotate(self.x_label_angle)
553
554 cr.set_source_rgba(*self.label_color)
555
547 for item in self.labels[HORZ]:556 for item in self.labels[HORZ]:
548 cr.set_source_rgba(*self.label_color)
549 width = cr.text_extents(item)[2]557 width = cr.text_extents(item)[2]
550 cr.move_to(x, self.dimensions[VERT] - self.borders[VERT] + 5)558 cr.move_to(x, y)
551 cr.rotate(self.x_label_angle)559 cr.save()
560 cr.set_matrix(rotation_matrix)
552 cr.show_text(item)561 cr.show_text(item)
553 cr.rotate(-self.x_label_angle)562 cr.restore()
554 x += step563 x += step
555 564
556 def render_vert_labels(self):565 def render_vert_labels(self):
557 cr = self.context566 cr = self.context
558 step = ( self.plot_height ) / ( len( self.labels[VERT] ) - 1 )567 step = ( self.plot_height ) / ( len( self.labels[VERT] ) - 1 )
559 y = self.plot_top568 y = self.plot_top
569 cr.set_source_rgba(*self.label_color)
560 for item in self.labels[VERT]:570 for item in self.labels[VERT]:
561 cr.set_source_rgba(*self.label_color)
562 width = cr.text_extents(item)[2]571 width = cr.text_extents(item)[2]
563 cr.move_to(self.borders[HORZ] - width - 5,y)572 cr.move_to(self.borders[HORZ] - width - 5,y)
564 cr.show_text(item)573 cr.show_text(item)
565574
=== modified file 'trunk/seriestests.py'
--- trunk/seriestests.py 2009-07-09 21:57:24 +0000
+++ trunk/seriestests.py 2009-10-07 10:00:26 +0000
@@ -1,8 +1,16 @@
1import cairo, math, random1import cairo, math, sys
22
3import cairoplot3import cairoplot
4from series import Series4from series import Series
55
6# non-random data for needs of visual comparison of changes
7if '--non-random' in sys.argv:
8 random = lambda : 1.0
9 print 'Plotting nonrandom data'
10else:
11 import random
12 random = random.random
13
6# Line plotting14# Line plotting
7test_scatter_plot = 115test_scatter_plot = 1
8test_dot_line_plot = 116test_dot_line_plot = 1
@@ -48,8 +56,8 @@
48 f = [math.exp(x) for x in t]56 f = [math.exp(x) for x in t]
49 g = [10*math.cos(x) for x in t]57 g = [10*math.cos(x) for x in t]
50 h = [10*math.sin(x) for x in t]58 h = [10*math.sin(x) for x in t]
51 erx = [0.1*random.random() for x in t]59 erx = [0.1*random() for x in t]
52 ery = [5*random.random() for x in t]60 ery = [5*random() for x in t]
53 data = Series({"exp" : [t,f], "cos" : [t,g], "sin" : [t,h]})61 data = Series({"exp" : [t,f], "cos" : [t,g], "sin" : [t,h]})
54 series_colors = [ (1,0,0), (0,0,0), (0,0,1) ]62 series_colors = [ (1,0,0), (0,0,0), (0,0,1) ]
55 cairoplot.scatter_plot ( 'cross_r_exponential_series.png', data = data, errorx = [erx,erx], errory = [ery,ery], width = 800, height = 600, border = 20, 63 cairoplot.scatter_plot ( 'cross_r_exponential_series.png', data = data, errorx = [erx,erx], errory = [ery,ery], width = 800, height = 600, border = 20,
@@ -77,6 +85,12 @@
77 cairoplot.dot_line_plot( 'dot_line_3_series_legend_series.png', data, 400, 300, x_labels = x_labels, 85 cairoplot.dot_line_plot( 'dot_line_3_series_legend_series.png', data, 400, 300, x_labels = x_labels,
78 axis = True, grid = True, series_legend = True )86 axis = True, grid = True, series_legend = True )
7987
88 #Speed test, many x_labels
89 data = range(1000)
90 x_labels = [str(x) for x in data]
91 cairoplot.dot_line_plot( 'dot_line_4_many_x_labels.png', data, 14000, 300, x_labels = x_labels,
92 axis = True, grid = True, series_legend = True )
93
80if test_function_plot :94if test_function_plot :
81 #Default Plot95 #Default Plot
82 data = lambda x : x**296 data = lambda x : x**2
@@ -142,7 +156,7 @@
142 cairoplot.vertical_bar_plot ( 'vbar_8_hy_labels_series.png', data, 600, 200, border = 20, display_values = True, grid = True, x_labels = x_labels, y_labels = y_labels )156 cairoplot.vertical_bar_plot ( 'vbar_8_hy_labels_series.png', data, 600, 200, border = 20, display_values = True, grid = True, x_labels = x_labels, y_labels = y_labels )
143 157
144 #Large data set158 #Large data set
145 data = Series([[10*random.random()] for x in range(50)])159 data = Series([[10*random()] for x in range(50)])
146 x_labels = ["large label name oh my god it's big" for x in data]160 x_labels = ["large label name oh my god it's big" for x in data]
147 cairoplot.vertical_bar_plot ( 'vbar_9_large_series.png', data, 1000, 800, border = 20, grid = True, rounded_corners = True, x_labels = x_labels )161 cairoplot.vertical_bar_plot ( 'vbar_9_large_series.png', data, 1000, 800, border = 20, grid = True, rounded_corners = True, x_labels = x_labels )
148 162
@@ -182,7 +196,7 @@
182 cairoplot.horizontal_bar_plot ( 'hbar_8_hy_labels_series.png', data, 600, 200, border = 20, series_labels = series_labels, display_values = True, grid = True, x_labels = x_labels, y_labels = y_labels )196 cairoplot.horizontal_bar_plot ( 'hbar_8_hy_labels_series.png', data, 600, 200, border = 20, series_labels = series_labels, display_values = True, grid = True, x_labels = x_labels, y_labels = y_labels )
183197
184 #Large data set198 #Large data set
185 data = Series([[10*random.random()] for x in range(25)])199 data = Series([[10*random()] for x in range(25)])
186 x_labels = ["large label name oh my god it's big" for x in data]200 x_labels = ["large label name oh my god it's big" for x in data]
187 cairoplot.horizontal_bar_plot ( 'hbar_9_large_series.png', data, 1000, 800, border = 20, grid = True, rounded_corners = True, x_labels = x_labels )201 cairoplot.horizontal_bar_plot ( 'hbar_9_large_series.png', data, 1000, 800, border = 20, grid = True, rounded_corners = True, x_labels = x_labels )
188202
@@ -242,8 +256,8 @@
242 f = [math.exp(x) for x in t]256 f = [math.exp(x) for x in t]
243 g = [10*math.cos(x) for x in t]257 g = [10*math.cos(x) for x in t]
244 h = [10*math.sin(x) for x in t]258 h = [10*math.sin(x) for x in t]
245 erx = [0.1*random.random() for x in t]259 erx = [0.1*random() for x in t]
246 ery = [5*random.random() for x in t]260 ery = [5*random() for x in t]
247 data = Series({"exp" : [t,f], "cos" : [t,g], "sin" : [t,h]})261 data = Series({"exp" : [t,f], "cos" : [t,g], "sin" : [t,h]})
248 series_colors = [ (1,0,0), (0,0,0) ]262 series_colors = [ (1,0,0), (0,0,0) ]
249 cairoplot.scatter_plot ( 'scatter_color_themes_series.png', data = data, errorx = [erx,erx], errory = [ery,ery], width = 800, height = 600, border = 20, 263 cairoplot.scatter_plot ( 'scatter_color_themes_series.png', data = data, errorx = [erx,erx], errory = [ery,ery], width = 800, height = 600, border = 20,
250264
=== added directory 'trunk/testscripts'
=== added file 'trunk/testscripts/compare.sh'
--- trunk/testscripts/compare.sh 1970-01-01 00:00:00 +0000
+++ trunk/testscripts/compare.sh 2009-10-07 10:00:26 +0000
@@ -0,0 +1,22 @@
1#!/bin/sh
2
3if [ $# -ne 3 ]
4then
5 echo "Compare .png files in two directories"
6 echo "Usage: ./compare.sh path1 path2 diffdir"
7 echo "Example: ./compare.sh . ../other ./diff"
8 exit
9fi
10
11for dir in $1 $2
12do
13 for i in $dir/*.png
14 do
15 convert $i $i.tiff
16 done
17done
18
19for i in `(cd $1; ls *.tiff)`
20do
21 perceptualdiff $1/$i $2/$i -output $3/$i.ppm
22done
023
=== added file 'trunk/testscripts/timeit.sh'
--- trunk/testscripts/timeit.sh 1970-01-01 00:00:00 +0000
+++ trunk/testscripts/timeit.sh 2009-10-07 10:00:26 +0000
@@ -0,0 +1,3 @@
1#!/bin/sh
2DIRNAME=`dirname $0`
3(cd $DIRNAME/..; python -m timeit -n 1 -v "import seriestests")

Subscribers

People subscribed via source and target branches