Hi all,
I tried to get a better understanding of Cairo drawing by implementing
this solution myself. This is just a proof-of-concept and I didn't do any
rigorous testing, but subjectively comparing the resize performance of a
Winston scatter plot of ~10000 points and this new solution, I noticed a
significant speed-up. Note that I still find it too slow, but that's
probably due to my lack of understanding of Cairo.
Basically, this is what I did:
In Cairo.jl, add the following two functions:
+function push_group(ctx::CairoContext)
+ if ctx.ptr == C_NULL
+ return
+ end
+ ccall((:cairo_push_group, _jl_libcairo), Void, (Ptr{Void},),ctx.ptr)
+ nothing
+end
+
+function pop_group(ctx::CairoContext)
+ if ctx.ptr == C_NULL
+ return
+ end
+ ptr = ccall((:cairo_pop_group, _jl_libcairo), Ptr{Void},
(Ptr{Void},),ctx.ptr)
+ pattern = CairoPattern(ptr)
+ finalizer(pattern, destroy)
+ pattern
+end
And this is my test code:
using Base.Graphics
using Cairo
using Tk
function example(num::Integer)
x = 100*rand(num)
y = 100*rand(num)
win = Toplevel("Scatter",800,600)
c = Canvas(win, 800,600)
pack(c,expand=true,fill="both")
function update(c)
r = 0.2
lw = 1.0
cc = r + (lw+1)/2 + 1
ctx = getgc(c)
set_coords(ctx,0,0,Tk.width(c),Tk.height(c),-2*cc,100+2*cc,-2*cc,100+2*cc)
set_source_rgb(ctx,1,1,1)
paint(ctx)
rectangle(ctx, 0,0,2*cc,2*cc)
clip(ctx)
push_group(ctx)
set_line_width(ctx,lw)
set_source_rgb(ctx,1,0,0)
arc(ctx,cc,cc,r,0,2*pi)
stroke_preserve(ctx)
fill_preserve(ctx)
p = pop_group(ctx)
reset_clip(ctx)
for i=1:num
save(ctx)
translate(ctx,x[i]-cc,y[i]-cc)
set_source(ctx,p)
paint(ctx)
restore(ctx)
end
reveal(c)
Tk.update()
end
c.resize = c->update(c)
end
I appreciate any comments on this. Thanks!
On Thursday, February 13, 2014 2:24:25 PM UTC+8, Mike Nolta wrote:
>
> Thanks Roger! I'll give this a try.
>
> -Mike
>
> On Wed, Feb 12, 2014 at 11:57 PM, Roger Herikstad
> <[email protected] <javascript:>> wrote:
> > Hi,
> > I'm enjoying the ease with which Winston allows me to create beautiful
> > plots. However, I often have the need to create scatter plots consisting
> of
> > ~1e5 points. This is currently too slow, and for those situations I
> resort
> > to Matlab using the excellent Matlab.jl
> > (https://github.com/lindahua/MATLAB.jl). I'm aware of a previous thread
> on
> > this list concerning plotting performance of a large number of lines,
> but I
> > believe scatter plots might be a different issue, since it would involve
> > drawing a separate path for each symbol in any case. I came across this
> > thread: http://comments.gmane.org/gmane.comp.lib.cairo/18734 where a
> similar
> > problem was addressed. Could something like that be implemented in
> Winston
> > as well?
> > After a cursory look at the the Cairo source code, it seems that the
> > suggested solution relies on functions that are currently not wrapped by
> > Cairo.jl, such as push_group/pop_group. I was considering trying to hack
> > this out myself, but my knowledge of Cairo graphics is virtually
> > non-existent. Anyway, I just thought I'd raise the issue in case someone
> > would want to pursue it.
> >
> > ~ Roger
>