Recently, while doing some volunteer website work for a music nonprofit, I needed to show the location of an event (Cormont Horn Camp) on a map of New Hampshire and Vermont. The image above shows what I made. In today’s post, I’ll show how I made it using MATLAB and Mapping Toolbox.
First, start with a special kind of axes called a geographic axes. In a geographic axes, data is plotted using latitude and longitude coordinates.
h_geoaxes = geoaxes
h_geoaxes =
GeographicAxes with properties:
Basemap: 'streets-light'
Position: [0.1300 0.1140 0.7750 0.8110]
Units: 'normalized'
Show all properties
Next, read low-resolution state boundaries into a geographic data table using readgeotable
. (Note: the data file usastatelo.shp is included with Mapping Toolbox.)
states = readgeotable("usastatelo.shp")
Shape | Name | LabelLat | LabelLon | PopDens2000 | |
---|---|---|---|---|---|
1 | geopolyshape | “Alabama” | 32.2827 | -86.9206 | 87.6000 |
2 | geopolyshape | “Alaska” | 64.6097 | -152.4593 | 1.1000 |
3 | geopolyshape | “Arizona” | 34.3451 | -112.0705 | 45.2000 |
4 | geopolyshape | “Arkansas” | 34.8350 | -91.8861 | 51.3000 |
5 | geopolyshape | “California” | 36.8223 | -119.6633 | 217.2000 |
6 | geopolyshape | “Colorado” | 39.0295 | -105.5440 | 41.5000 |
7 | geopolyshape | “Connecticut” | 41.5106 | -72.7627 | 702.9000 |
8 | geopolyshape | “Delaware” | 39.1071 | -75.4942 | 401 |
9 | geopolyshape | “Florida” | 28.3914 | -82.8483 | 296.4000 |
10 | geopolyshape | “Georgia” | 32.5803 | -83.0864 | 141.4000 |
11 | geopolyshape | “Hawaii” | 21.0458 | -154.5259 | 188.6000 |
12 | geopolyshape | “Idaho” | 45.0105 | -114.6199 | 15.6000 |
13 | geopolyshape | “Illinois” | 39.7424 | -89.1980 | 223.4000 |
14 | geopolyshape | “Indiana” | 39.4482 | -86.5771 | 169.5000 |
I’m specifically interested in New Hampshire and Vermont.
new_hampshire = states(states.Name == "New Hampshire", :)
Shape | Name | LabelLat | LabelLon | PopDens2000 | |
---|---|---|---|---|---|
1 | geopolyshape | “New Hampshire” | 43.9080 | -71.5591 | 137.8000 |
vermont = states(states.Name == "Vermont", :)
Shape | Name | LabelLat | LabelLon | PopDens2000 | |
---|---|---|---|---|---|
1 | geopolyshape | “Vermont” | 44.0435 | -72.5565 | 65.8000 |
The function geoplot
can plot various kinds of latitude-longitude data, including the geopolyshapes in the usastatelo dataset.
geoplot(new_hampshire,"FaceColor",[0.3 1.0, 0.675])
hold on
geoplot(vermont,"FaceColor","yellow")
hold off
Now I’ll mark the location of the event. I looked up the latitude and longitude coordinates.
cormont_lat = 43.675833;
cormont_lon = -72.040556;
hold on
geoplot(cormont_lat, cormont_lon, Marker = "o", ...
MarkerEdgeColor = "black", ...
MarkerFaceColor = "black", ...
MarkerSize = 3)
text(cormont_lat, cormont_lon, [" Cormont" ; " Horn Camp"], ...
FontSize = 6, ...
FontAngle = "italic", ...
HorizontalAlignment = "left", ...
VerticalAlignment = "top");
hold off
I wanted to show the Appalachian Trail on the map. I did some online searching and found a file with latitude-longitude coordinates for the trail.
s = load("at_area_shape.mat");
at_shape = s.at_area_shape;
at_geopoly = geopolyshape(at_shape.Lat, at_shape.Lon);
I used the function geoclip
to clip the Appalachian Trail coordinates to the states of New Hampshire and Vermont. Then, I used geoplot
once again to plot the trail. For labeling the trail, the MATLAB function text
works just fine with geographic axes.
at_clipped_nh = geoclip(at_geopoly, new_hampshire.Shape);
at_clipped_vt = geoclip(at_geopoly, vermont.Shape);
trail_color = [.75 .75 .75];
hold on
geoplot(at_clipped_nh, FaceColor = trail_color, ...
EdgeColor = trail_color)
geoplot(at_clipped_vt, FaceColor = trail_color, ...
EdgeColor = trail_color)
hold off
at_label_lat = 44 + 20/60;
at_label_lon = -71 - 22/60;
text(at_label_lat, at_label_lon, ...
"Appalachian Trail", ...
FontSize = 6, ...
Rotation = 34, ...
HorizontalAlignment = "center", ...
VerticalAlignment = "bottom")
It’s time to fix up the background. I don’t need a basemap or visible latitude and longitude coordinates.
h_geoaxes.Basemap = "none";
h_geoaxes.Visible = "off";
Finally, I wanted to place a few key landmarks, including two airports (Manchester-Boston Regional and Patrick Leahy Burlington) and the two capitol cities (Concord and Montpelier). MATLAB code files and MATLAB graphics can include Unicode characters, which made it easy to show airplane icons on the map.
mht_lat = 42.93250;
mht_lon = -71.43556;
btv_lat = 44.47194;
btv_lon = -73.15333;
concord_lat = 43.206667;
concord_lon = -71.538056;
mp_lat = 44.259444;
mp_lon = -72.575833;
plane_rotation = 30;
hold on
text(vermont.LabelLat, vermont.LabelLon, "VT", ...
HorizontalAlignment = "center")
text(new_hampshire.LabelLat, new_hampshire.LabelLon, ...
"NH", HorizontalAlignment = "center")
text(mht_lat, mht_lon, "✈", ...
FontSize = 16, ...
VerticalAlignment = "middle", ...
HorizontalAlignment = "center", ...
Rotation = plane_rotation);
text(btv_lat, btv_lon, "✈", ...
FontSize = 16, ...
VerticalAlignment = "middle", ...
HorizontalAlignment = "center", ...
Rotation = plane_rotation);
text(concord_lat, concord_lon, "★", ...
HorizontalAlignment = "center", ...
VerticalAlignment = "middle")
text(mp_lat, mp_lon, "★", ...
HorizontalAlignment = "center", ...
VerticalAlignment = "middle")
hold off
With the map now completed, I can use exportgraphics
to save the result to an image file at the desired resolution.
exportgraphics(h_geoaxes,"cormont_location.png", ...
Resolution = 600)