How can I speed up plotting lines over a map?

13 visualizaciones (últimos 30 días)
Stefan
Stefan el 16 de Ag. de 2016
Comentada: Colin el 20 de Mzo. de 2023
Hi,
I am hoping to speed up the plotting process in my code. I'll describe it better below, but essentially I'm plotting lines between points over a map repeatedly as those points move from iteration to iteration. I've identified the bottleneck but it is very internal (involving axes layering) and I'm not aware of how to address it. Additionally, I have made a list of possible inefficiencies/improvements I have gathered from other questions but I was hoping to get some feedback before changing my code structure (it is quite bulky). I am considering rewriting my code in Python or C, but I really like the Mapping Toolbox in MATLAB so I would rather not change languages if possible.
What my code is doing:
I'm limited in what code I can post, but here is an overview of the functionality. Data from the WMS server are downloaded and layered. This is stored; it doesn't happen every iteration so it is OK to be slow. At the beginning of an iteration, the map is plotted using geoshow(). Points are plotted on and over the map using plotm(lat1,lon1,z1,...) and are connected with linem(lat1,lat2,lon1,lon2,z1,z2). Some of these points move and some of them don't but the lines always move. The figure is reset by clf('reset'). The data generated is stored and the figure is captured for later playback. Repeat.
How long it's taking:
Five iterations takes nearly a minute (with profiler on) and 200 iterations might take around 40 minutes. I'm needing to plot between 200 and 1500 iterations at a time, change some values, and repeat. I believe this time can be greatly reduced since there appears to be only one bottle neck.
The bottleneck:
Obviously, the bottleneck is in the plotting. When I run the code in "no plotting mode," 5 iterations take less than 5 seconds (there are a lot of calculations I didn't mention above). When running profiler, I can isolate the largest time consumer within that process:
specifically,
which is the internal MATLAB function having code
The slowest part of the code seems to be where MATLAB is moving each new layer to the top of the axes (highlighted red, above).
Improvements I have made or can make:
I know many aspects of the code are not optimal. For example, I can modify the linem objects instead of creating a new one every iteration using set() and the map and stationary points don't need to be re plotted every iteration. Some things I've tried, in addition to small things like setting limits to constants:
figure(1);set(groot,'CurrentFigure',1);
ax = gca;
ax.SortMethod = 'childorder';
set(1,'CurrentAxes',ax)
set(1, 'renderer', 'opengl')
Is there a way I can address the layering issue in addition to implementing the above improvements (modify lines instead of plotting)? I don't need any of the lines in particular stacking order, as along as they are all above the map surface. If I modify the line objects using set() instead of redrawing them, will the stacking order only be done once per run or will it still be executing for every iteration? Any insight would be greatly appreciated!
Stefan D.
  2 comentarios
Chad Greene
Chad Greene el 16 de Ag. de 2016
How big is the background map? Sometimes the mere presence of a large background map or image can slow everything down to a crawl. This happens a lot with the mapping toolbox in particular, where in many cases each pixel is placed individually according to the map projection. It's the difference between this:
imagesc(rand(5000))
which plots pretty quickly, and
pcolor(rand(5000))
shading flat
which might take a minute to render, and then slows everything else down if you try to plot a simple line on top of it.
Stefan
Stefan el 29 de Ag. de 2016
Thanks for your input - you are probably right. My map is as small as I can get away with but still large enough to slow things down, apparently. Any suggestions on how to speed things up, other than lowering the map size?

Iniciar sesión para comentar.

Respuesta aceptada

Kelly Kearney
Kelly Kearney el 29 de Ag. de 2016
By clearing the map and replotting, you're forcing the plotting functions to repeat a lot of the projection calculations unnecessarily. In addition, the Mapping Toolbox functions tend to be a bit bloated when it comes to graphics overhead... they seem to have been designed with small datasets and slow, interactive data exploration in mind.
So I think you could definitely speed things up by plotting just once and then changing the X, Y, Z, and CData properties of existing objects as necessary. This may require you to do the projection calcs yourself, but I find that's usually faster than relying on the internal plotm/linem/whateverm projections.
If you post a bit of example code, perhaps we can give you some more detailed suggestions.
  2 comentarios
Stefan
Stefan el 30 de Ag. de 2016
Thanks for the input Kelly. So, for those who are interested, I changed my code to modify plotting objects (like lines and points) rather than create a new one every time. The result plotted about 3x faster per iteration. Running profiler like I did above yields very different sources of time consumption. At 3 seconds per iteration with 500 iterations, it is still much slower than I would hope for but I'll take what I can get. I suppose MATLAB's Mapping Toolbox isn't exactly made for what I'm doing.
Chad Greene
Chad Greene el 31 de Ag. de 2016
Stefan,
If you can project the coordinates yourself and use imagesc instead of geoshow, that might speed things up. It's hard to offer specific advice though, because we can't see how you're using geoshow. It's one of those functions that is designed to be smart and automatically make decisions about how to plot data based on what you give it, and you can give it a lot of different forms of data. What information are you feeding to geoshow, and what are the dimensions of the underlying map?
If the underlying map contains more pixels than the final map you plan to generate, you might as well resize. You can resize the map, and, if you're giving geoshow grids of lats and lons you can resize them too with the Image Processing Toolbox function imresize. If you do this:
map_r = imresize(map,0.5);
lat_r = imresize(lat,0.5);
lon_r = imresize(lon,0.5);
it'll cut the dimensions of the underlying map in half, which means plotting 1/4 of the total number of pixels. And plotting should speed up accordingly.

Iniciar sesión para comentar.

Más respuestas (1)

Henry Sieber
Henry Sieber el 11 de Nov. de 2020
I was having this same problem (I know this was 4 years ago) but I was using fillm in a similar way and it took 12 hours to complete the map of salinity, and so I dug into the MATLAB code and found that the restacking was the process that was taking forever and its sole purpose is to "Set the stacking order for the decorations (except for the frame, which was placed on the bottom at the time it was constructed)." which seemed unnecesarry since I was not drawing anything over any of these decorations and even if I was I could move them to the top when I finish my 16183 repetitions. so in the matlab file patch.m located in /Applications/MATLAB_R2020b.app/toolbox/map/mapdisp I commented out line 75 "map.graphics.internal.restackMapAxes(h0)" so that it does not restack the axes everytime I plot a pixel, and it took my 12 hour processing time down to 3 minutes. I hope this helps someone else having the same problem.
One note is that you need to unlock the matlab file to be able to write to it, it gives you the prompt to overwrite it on mac but on pc you need to go to properties and manually set it to write access to users. Once you have unlocked the file and made the change you need to run the code once in MATLAB which will give you an error saying there are not enough arguments but this is just so that it compiles your change otherwise it will have the same performance.
  2 comentarios
Tim Divett
Tim Divett el 21 de Oct. de 2021
Editada: Tim Divett el 21 de Oct. de 2021
Thanks, I just encountered a similar problem when moving code to version 2021b. A call to mapshow was very slow. Commenting out map.graphics.internal.restackMapAxes(h) from line 52 of toolbox/map/map/private/mapvecshow.m sped this up by a factor of 100. The old 2014 version of this file only called this function if ~matlab.graphics.internal.isGraphicsVersion1 which is apparently not available in 2021b. Doesn't seem to cause any problems with the map I'm trying to create for now.
Colin
Colin el 20 de Mzo. de 2023
I had the same issue with geoshow('DisplayType','Point') and solved it by following the above advice applied to geovecshow.m (in toolbox/map/map/private). For other DisplayTypes, the geoshow wrapper can be made to display which function (geovecshow, georastershow, etc) it's actually using. I saw a speed-up of about 20x by commenting out the restacking, with no apparent detriment to the plots themselves.

Iniciar sesión para comentar.

Categorías

Más información sobre Graphics Performance en Help Center y File Exchange.

Productos

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by