How to create a bubble plot with Antarctic Mapping Tool

I'm fairly new to Matlab but I had to learn it because there are some specific kind of plot I need to obtain and that should be easily plotted using Matlab add ons Antarctic Mapping Tools and BedMachine.
And to be honest. The code work, like I am able to obtain what I need with some simple lines of code
Lat = linspace(-76,-75,30)';
Long= linspace(120, 150, 30)';
Sodium=randi(50,30,1);
scatterps(Lat, Long, Sodium,'filled')
legend('Sodium (ppb)')
box on
mapzoomps('sw')
graticuleps(-88:2:-76,-150:30:180)
scalebarps
bedmachine('surface','contour', 0:100:5000)
give me the plot I need: some dots of my sample's concentration over the surface of antarctica where I am also highlighting the surface elevation. The size of the dot, is correlated to the concentration of the sample (Sodium).
But my question is... the current legend doesn't show any information on the size of the dots. I tried to follow Bubblechart's tutorial, but of course they refer to a different kind of plots. I'm asking because I tried to use a color scale, but it's
1) extremely hard to read
2) every time I add the elevation contour lines, they are also added to the color scale and of course this makes it impossible to read the actual concentration.
Am I missing something? I know I'm new to Matlab and programming in general but I can't find any solution on the Documentation

 Risposta accettata

First off, excellent job on creating a minimal working example. That really helps me understand where you're at and what you're trying to do. I was able to create this plot using your code:
We'll tackle your Point #2 first: When you try to plot color-scaled circles in the same map as color-scaled contour lines, Matlab gets confused. That's not your fault. That's Matlab's fault. The ability to plot two colormaps on the same plot is something users have been requesting for decades, but for some reason Matlab is still refusing to allow it. There are a few workarounds, but they're sort of clunky and probably not worth getting into here.
For your case, I recommend that you either use color for surface elevation, or you use color for the scattered data. Here's how you could use color for the scattered data and make all of the contour lines gray:
Lat = linspace(-76,-75,30)';
Long= linspace(120, 150, 30)';
Sodium=randi(50,30,1);
scatterps(Lat, Long,50, Sodium,'filled')
legend('Sodium (ppb)')
box on
mapzoomps('sw')
graticuleps(-88:2:-76,-150:30:180)
scalebarps
h = bedmachine('surface','contour',0:100:5000,'k');
caxis([min(Sodium(:)) max(Sodium(:))])
h.Color = 0.6*[1 1 1]; % gray contour lines
If you want to label those contours, you'll have to take a manual approach. Instead of simply calling bedmachine to plot the data, you'll have to load the bedmachine data using the x and y limits of the map, then contour and label it, like this:
[sfz,x,y] = bedmachine_data('surface',xlim,ylim); % enough data to fill the map
[C,h] = contour(x,y,sfz,0:100:5000,'k');
caxis([min(Sodium(:)) max(Sodium(:))])
h.Color = 0.6*[1 1 1]; % gray contour lines
clabel(C,h,'labelspacing',1000,'fontsize',7,'color',0.6*[1 1 1])
You could use other data like a background image for better context:
modismoaps('contrast','low')
h.Color = 'r';
Or if you want to use the size of circles to represent data values, here's how you can do it (caveat below).
Lat = linspace(-76,-75,30)';
Long= linspace(120, 150, 30)';
Sodium=randi(50,30,1);
circleps(Lat, Long,Sodium,'facecolor',[.01 .26 .87],'facealpha',0.8)
box on
mapzoomps('sw')
graticuleps(-88:2:-76,-150:30:180)
scalebarps
bedmachine('surface','contour',0:100:5000);
% Get the current axis limits:
xl = xlim;
yl = ylim;
% Get the coordinates of five points near the top left corner:
[lat_legend,lon_legend] = ps2ll(xl(1) + diff(xl)/10,yl(2)-diff(yl)/15-(1:5)*diff(yl)/15);
% Plot circles of radii 5 to 45 km:
circleps(lat_legend,lon_legend,5:10:45,'facecolor',[.01 .26 .87],'facealpha',0.8)
% Label the circles:
textps(lat_legend,lon_legend,{'5';'15';'25';'35';'45 ppb'},'horiz','center','vert','middle','color','w')
In the map above, the circles are sized based on 1 km radius per 1 ppb Sodium. And you could easily multiply the circle radii by some factor to make them visible on your map.
A word of caution about this approach though: On the face of it, it makes sense to scale the size of circles with the numeric value of your Sodium data, and this type of bubble chart is very common in geospatial data visualization, especially in popular media. However, Edward Tufte opened my eyes to the fact that size-scaled bubble charts are intrinsically inaccurate.
In the example above, I've scaled the circle raddi linearly with the Sodium data, but of course the area of a circle scales as the square of the radius. In this sense, the linear scaling of the radius exaggerates the size of the large data and minimizes the small data.
It might be better to scale the circle radii with the square root of the Sodium data, because then the amount of ink on the page devoted to each circle will scale linearly with the underlying data. However, the human brain does not perceive the size of circles as a linear function of radius or area. In truth, we tend to perceive circle sizes somewhere in between.
There's a feature in ArcGIS that acknowledges the fact that neither radius nor area is a good way to scale numeric data, and so in ArcGIS you can select an option to plot circle sizes based on some approximate human perception, but that introduces yet another problem, because then it becomes impossible to measure any part of the visualization and tie it directly to the underlying data.
Anywho, I try to stick with color scaling for numeric data, and single-color labeled contours and/or hillshade when plotting surface elevation or context. But do whatever makes most sense for your data.

5 Commenti

Wow! This was even more than what I expected, thanks a ton!
I might try to use the color scale then, but I've found that either I'm slightly color blind or something like that because I have an extremely hard time trying to pin point the exact color of a small plot on a graph both on a dark or white backgound, and the bubble plot was a way for me to trying to give a visual rappresentation of these data without forcing people with an ever harder time than me to see color to understand what I'm talking about, but it's definitely worth investigating more to find an appropriate solution.
For now these plots will only serve as a small visual aid to quickly assesses the data (i.e. identify whether or not there is an evident pattern of Sodium's concentration and stuff like that). I'll look in more precise ways to display the data.
Once again, thanks a ton! It was seriously more than what I anticipated :D
Fantastic; I'm glad this helped! If the question is resolved, do you mind accepting the answer?
No problem! Just a small last question, when you said to set the limits for x and y in order to have enough bedmachine data, how do I set them?
Ah, I just used xlim and ylim in the example above, like this:
[sfz,x,y] = bedmachine_data('surface',xlim,ylim);
And the reason I'm using xlim and ylim is because they simply return the x and y limits of the current plot. Make sure you already have your map open and zoomed to the area of interest if you do it this way. Otherwise, xlim and ylim will won't be of much use.
Alternatively, you could do
[sfz,x,y] = bedmachine_data('surface',Lat,Lon,'buffer',100);
or something like that, which would load enough bedmachine data to cover all your Sulfur data, plus 100 km on all sides for context.
Oh ok, nevermid, I'm used to R where I'd have to specify the actual limits and I thought that was the case, not that xlim and ylim were already built in functions that "extract" these values from the current plot.
Once again, thank you so much

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Geodesy and Mapping in Centro assistenza e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by