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 
>

Reply via email to