5

I am dealing with a structured grid. I just wanna add to the plot a text of the type (m,n) that indicates the indices of each node. And maybe in the future the value of the variable instead. I use the text function. I profiled the code and most of the time is spent in that function. It is only a 101*101 grid, if you increase it the code is basically stuck. I already optimized it avoiding loops for text and spritnf, but it still too slow. Moreover, once the plot is created it is very stuck and it takes a few seconds every time to pan or zoom. See on the follow a minimal example. I also added the patch that I use to display the grid. (I use patch because I want to plot some grid quantities for each cell and I want to keep it general in case I move to an unstructured mesh with irregular polygons. Patch is superfast though, no prob with it). Any suggestion to speed this up? thanks

    %define grid and grid numbering
    DX = 10 ; %=DY
    mmax = 101; %= number of nodes in x
    nmax = mmax %= number of nodes in y
    [ x y ] = meshgrid(0:DX:DX*(mmax-1),0:DX:DX*(mmax-1)); %grid
    [ mMAT nMAT ] = meshgrid(1:mmax,1:nmax); %grid numbering
    %
    %display patch
    %
    cont = 0
    for m=2:mmax
        for n=2:nmax
            cont=cont+1;
            Xpatch(1:4,cont) = [ x(n-1,m-1) ; x(n-1,m) ; x(n,m) ; x(n,m-1) ] ;% ii+1 since it has the BC
            Ypatch(1:4,cont) = [ y(n-1,m-1) ; y(n-1,m) ; y(n,m) ; y(n,m-1) ] ;
            Zpatch(cont) = 1;
        end
    end
    hpatch3 = patch(Xpatch(:,:),Ypatch(:,:),Zpatch(:)');
    %
    % display node indices
    %
    charINPUT = regexp(sprintf('(%d,%d)\n',mMAT(:),nMAT(:)),'(?<=\s*)(\S*)(?=\n)','match'); % use regexp to vectorize sprintf and so avoid slow loops with sprintf 
    text(x(:),y(:),charINPUT(:),'Clipping', 'on');
    set(gcf,'position',[9 40 1350 650])
    set(gcf,'PaperPositionMode','auto')
Millemila
  • 1,612
  • 4
  • 24
  • 45
  • Just an idea, another function that offers text writing is annotation. Although it leaves this filling that annotation is heavier, you can check if it works better. But I wouldn't count very much that there is a better approach than `text`, it is the matlab builtin solution for that. – Werner Oct 05 '13 at 00:24
  • Have a look here: http://stackoverflow.com/questions/4940561/does-matlab-execute-a-callback-when-a-plot-is-zoomed-resized-redrawn By the way, your edit to my answer on your other question was overzealous so reviewers thankfully rejected it. Try not to fundamentally change the content of posts... just small edits, if anything at all. Let me know if there is a number or something specific to add and I'll make the change. Thanks. – chappjc Oct 05 '13 at 00:26
  • Mmm I checked the help annotation does not allow you to use a vector you have to cycle right?I doubt its faster – Millemila Oct 05 '13 at 00:56
  • @Chappjc: thanks I am looking on it. Looks a good idea, text function is simply slow I guess on the entire area. As for the other thread: so bad it took me half an hour. ok does not matter thanks. – Millemila Oct 05 '13 at 00:57

3 Answers3

3

Guys I found the solutions. 100 times faster if you just set hittest to 'off'!!!!! I did this:

text(x(:), y(:), charINPUT(:), 'Clipping', 'on','hittest', 'off');

and my life changed.

Thanks. A.

saastn
  • 5,717
  • 8
  • 47
  • 78
Millemila
  • 1,612
  • 4
  • 24
  • 45
2

The problem is that text is simply displaying too much. The approach I would suggest is to utilize figure and axes callbacks (or undocumented listeners) to add the text (or annotations) when you reach a certain zoom level, and to maintain which text labels are displayed depending on the zoom and pan. In a nutshell, the callbacks would check the xlim and ylim properties of the axis and add the appropriate text for that range (and delete any old text).

If this seems like a solution you would be happy with, give it a shot. I can give you some hints and/or examples later. Thanks to Werner for the tip about using listeners.

chappjc
  • 30,359
  • 6
  • 75
  • 132
  • Thanks it looks like the good way to go. Strange though I see many program that vizualises numerical results that handle tens of thousands of texts displaying the nodal value of the variable on the same region with no problems at all. It looks like text is just a plain slow function. I cant believe that. – Millemila Oct 05 '13 at 01:00
  • 1
    @Alberto Besides the documented way, provided by chappjc within a comment on your question post, for listening to zoom and pan, another undocumented way for listening to `xlim` and `ylim` changes (which I prefer because you can set many listeners without having to care about your function handles) can be seen [here](http://undocumentedmatlab.com/blog/setting-axes-tick-labels-format/). Btw, this syntax changes when using HG2 to: `listener = addlistener(curAxes,'XLim','PostSet',functionHandle);` – Werner Oct 05 '13 at 01:38
  • 1
    Yep. +1 for Yair. It's really worth getting on his mailing list. – chappjc Oct 05 '13 at 01:43
  • Good thanks Werner. But so are we here saying that there is nothing to do, when 10000 texts are plotted it is just plain slow?And we should not plot all of the when zooming out? – Millemila Oct 05 '13 at 21:01
0

I had a similar problem. I found that reducing the number of calls to text (in my case from ~500 to 1) by providing it with vectors rather than many individual calls, resulted in a significant performance benefit. In my specific case, I went from ~25s to display 1 graph to ~2s.

For me, the hittest off method did not have any performance benefit - though in my case there aren't any zooming/clipping concerns so maybe this explains the difference to other people's experience.

Chris
  • 1