Beautiful Ridge maps with Python | by Thiago Carvalho | Towards Data Science

This visualization is the result of the sweet combination of elevation maps and ridge plots.
It uses multiple horizontal lines to represent the elevation of the terrain, like tracing the peak of various latitudes, one above the other.
The result is a very cool-looking map that shapes the mountains and different altitudes in a particular area.
I’m not sure about actual applications for this visualization besides making a good-looking front page for a report or making that regional analysis PowerPoint shine. But they are some very appealing maps that deserve some attention.
To quickly create our visualization, we can use ridge_map.
The package uses elevation data from SRTM, Matplotlib to draw the chart and even detect lakes with Scykit and Numpy.
After installing, we can test it by importing ridge_map and running plot_map without any parameters. We should get a map of The White Mountains.
from ridge_map import RidgeMapRidgeMap().plot_map()
Cool. Now let’s try a different location.
First, we’ll need some coordinates. I used Google Maps to get them. You can also display the map as ‘Terrain’ so you’ll get an idea of how your final visualization might look.
Once you find what you want, you can right-click the map to get the coordinates.
The Ridge map will require two sets of coordinates, one for the bottom left and another for the top right.
(-123.2510, 49.6902, -122.1194, 50.3446)(Bottom Left Long, Bottom Left Lat, Top Right Long, Top Right Lat)
Google’s coordinates are in the opposite order, Lat/ Long, so we need to invert them.
# coordinatesbl = [49.6902343443372, -123.25105812920076][::-1]tr = [50.34462404053542, -122.11945787458642][::-1]rm = RidgeMap(bl + tr)values = rm.get_elevation_data()rm.plot_map(values=rm.preprocess(values=values), label=None)
We start by defining RidgeMap and passing the coordinates to the constructor.
Then we use get_elevation_data to retrieve a NumPy array with our specifications. Here we have three handy arguments. Let’s try them.
# coordinatesbl = [49.6902343443372, -123.25105812920076][::-1]tr = [50.34462404053542, -122.11945787458642][::-1]rm = RidgeMap(bl + tr)values = rm.get_elevation_data(num_lines=160,                                elevation_pts=800,                                viewpoint="south")rm.plot_map(values=rm.preprocess(values=values), label=None)
That’s better!
The method get_elevation_data allows us to select the viewpoint and how much detail our visualization will have.
The preprocess method will enable us to configure the elevation ratio to exaggerate hills and mountains and configure the water detection. Where water_ntile deletes data based on the percentile of the elevations and lake_flatness deletes on the variation within three squares.
# coordinatesbl = [49.6902343443372, -123.25105812920076][::-1]tr = [50.34462404053542, -122.11945787458642][::-1]rm = RidgeMap(bl + tr)values = rm.get_elevation_data(num_lines=160,                                elevation_pts=800,                                viewpoint="south")rm.plot_map(values=rm.preprocess(values=values,                                  water_ntile=0,                                  lake_flatness=8,                                 vertical_ratio=80),             label=None)
All those arguments from get_elevation_data and preprocess are beneficial but sometimes tricky to use.
For even more aesthetic customizations, we have the plot_map method. There we can configure things like colors, line width, and label.
import seaborn as sbcmap = sb.light_palette("#69d", as_cmap=True)# coordinatesbl = [49.6902343443372, -123.25105812920076][::-1]tr = [50.34462404053542, -122.11945787458642][::-1]rm = RidgeMap(bl + tr)values = rm.get_elevation_data(num_lines=160,                                elevation_pts=800,                                viewpoint="south")rm.plot_map(values=rm.preprocess(values=values,                                  water_ntile=0,                                  lake_flatness=8,                                  vertical_ratio=80),             label=None,            line_color=cmap,            kind="gradient",            linewidth=1,            background_color='black',            size_scale=15)
Ridge map allows us a lot of customizations. For all the rest, we also have Matplotlib.
The plot_map method returns the axes, so we can pretty much change whatever we want.
import seaborn as sbimport matplotlib.pyplot as pltcmap = sb.light_palette("#69d", as_cmap=True)# coordinatesbl = [49.6902343443372, -123.25105812920076][::-1]tr = [50.34462404053542, -122.11945787458642][::-1]whistler = [50.11262255339053, -122.96522325554356][::-1]rm = RidgeMap(bl + tr)# convert annotation coordinateswhistler_coords = ((whistler[0] - rm.longs[0])/(rm.longs[1] - rm.longs[0]),(whistler[1] - rm.lats[0])/(rm.lats[1] - rm.lats[0]))values = rm.get_elevation_data(num_lines=160,                                elevation_pts=800,                                viewpoint="south")ax = rm.plot_map(values=rm.preprocess(values=values,                                  water_ntile=0,                                  lake_flatness=8,                                  vertical_ratio=80),             label=None,            line_color=cmap,            kind="gradient",            linewidth=1,            background_color='black',            size_scale=15)ax.plot(*whistler_coords, '.',        color='white',        transform=ax.transAxes,        zorder=len(values)+10)ax.text(whistler_coords[0]+0.01,         whistler_coords[1]+0.02,         'Whistler',        fontproperties=rm.font,        size=20,        color="white",        backgroundcolor='black',        transform=ax.transAxes,        verticalalignment="bottom",        zorder=len(values)+10)
Overall in my experience, this visualization requires a lot of experimentation. Since it’s more artistic than analytical, you’ll need to test different variables and see what happens until you find something you like.
Even though I don’t require maps like these, I had a lot of fun playing around with these visualizations and will use them again to spruce up my presentations.
I created all images in this post with Ridge Map. You’re welcome to use them as you like.
Thanks for reading. I hope you enjoyed it :)
More Python DataViz tutorials.