Creating your own custom maps
Other Ways to Find and Map Places
Figure 5 shows another map that I created by just copying, and executing without any change, another code sample found on the prettymaps homepage. I am including it here because, besides showing how different these maps can be from each other at the purely visual level, it uses another OSM feature that is worth knowing. The map shows the Lagoa dos Patos in Brazil, and Listing 2 shows the relevant parts of the prettymaps script that generates it.
Listing 2
Finding Places by Their OSM Identifier
01 fig, ax = plt.subplots(figsize = (10, 12), constrained_layout = True) 02 03 def postprocessing(layers): 04 layers['perimeter'] = layers['perimeter'].buffer(2000) 05 return layers 06 07 layers = plot( 08 'R2709093', 09 ... 10 postprocessing = postprocessing, 11 12 drawing_kwargs = { 13 'perimeter': {'fill': False, 'ec': '#6da8c2', 'lw': 2, 'zorder': 3}, 14 }, 15 16 osm_credit = {'x': -.08, 'y': .02, 'color': '#2F3737'} 17 ) 18 19 # Set bounds 20 xmin, xmax = ax.get_xlim() 21 ymin, ymax = ax.get_ylim() 22 dx, dy = xmax-xmin, ymax-ymin 23 ax.set_xlim(xmin+.15*dx, xmax-.15*dx) 24 ax.set_ylim(ymin+.0*dy, ymax-.0*dy)
Figure 6 is what the same lagoon looks like inside OpenStreetMap, plus the unique numeric identifier. Inside the OSM database, each "object" has a unique numeric identifier that is visible in the online map when you select that object. As you can see comparing Figure 6 with line 8 of Listing 2, you can use that identifier to directly define places in prettymaps! This capability may be very useful if you start using prettymaps to generate many maps of many places, maybe fetching their identifiers with some other script.
Other relevant parts of Listing 2 are lines 4 and 13, which process the perimeter of the map in a different way than Listing 1, and the final six lines, which set the borders of the drawing to make sure that no part of the lagoon is cut off the map. To see in detail how those instruction work, download that example and try to change the numeric constants in lines 23 and 24.
As final proof of the great versatility of prettymaps, check out Figure 7, which was generated from another code sample found on the website. Figure 7 shows a map of three adjacent neighborhoods of the city of Porto Alegre, Brazil (Figure 8), and nothing else. What's more, each neighborhood is painted with different colors.
The code excerpt in Listing 3 shows how to obtain this result. To begin with, you must define a hash, an associative array in which each element is associated with a key. In Listing 3, that hash is called places
(lines 4 to 8). Each line of that array is about one of the places that should be drawn. More specifically, each line defines a list of colors, in the same format described before, associated with a key that is the name of a neighborhood to fetch from OpenStreetMap and then draw. Then, you must wrap the same calls to the plot
and drawing_kwargs
functions of the previous example in one loop (line 10) that handles one neighborhood at a time. This happens because every iteration of that loop loads one key from the places
array, calling it place
, and loads the corresponding list of colors into an auxiliary variable called palette
. Then, as you can see in lines 12 and 17, each call to plot
and drawing_kwargs
uses the place name and colors that are currently loaded into those two variables. The autoscale
function in the last line ensures, with a different method than that used by Listing 2, that the whole drawing will fit in the image.
Listing 3
Mapping Adjacent Places in Different Styles
01 fig, ax = plt.subplots(figsize = (15, 12), constrained_layout = True) 02 fig.patch.set_facecolor('#F9F8F8') 03 04 places = { 05 - 'Farroupilha, Porto Alegre': ['#EEE4E1', '#E7D8C9', '#E6BEAE'], 06 - 'Cidade Baixa, Porto Alegre': ['#49392C', '#77625C', '#B2B1CF', '#E1F2FE', '#98D2EB'], 07 - 'Bom Fim, Porto Alegre': ['#BA2D0B', '#D5F2E3', '#73BA9B', '#F79D5C'], 08 } 09 10 for i, (place, palette) in enumerate(places.items()): 11 plot( 12 place, 13 ... 14 drawing_kwargs = { 15 'perimeter': {'fill': False, 'lw': 0, 'zorder': 0}, 16 'streets': {'fc': '#F1E6D0', 'ec': '#2F3737', 'lw': 1.5, 'zorder': 3}, 17 'building': {'palette': palette, 'ec': '#2F3737', 'lw': 1, 'zorder': 4}, 18 }, 19 20 ) 21 22 ax.autoscale()
Try prettymaps!
The examples I have presented are enough to generate thousands of maps, each with a distinct style, with very little effort once you have installed prettymaps and all its dependencies. What's more, you may use Matplotlib's capabilities to add both captions [13] and generic images [14] to all your maps, for any conceivable purpose. It would then be quite easy, for example, to create infographics that show different maps, each associated to charts generated from some statistical data about the same area. Isn't free software wonderful?
Infos
- OpenStreetMap: https://openstreetmap.org
- Stop at Zona-M blog: https://stop.zona-m.net/tag/openstreetmap/
- prettymaps: https://github.com/marceloprates/prettymaps
- prettymaps examples for Jupyter Notebook: https://nbviewer.org/github/marceloprates/prettymaps/blob/main/notebooks/examples.ipynb
- More examples on GitHub: https://github.com/zaataylor/maps
- OSMnx: https://github.com/gboeing/osmnx
- Shapely: https://pypi.org/project/Shapely/
- vsketch: https://github.com/abey79/vsketch
- Matplotlib: https://matplotlib.org/
- IPython: https://ipython.org/
- prettymaps subreddit: http://www.reddit.com/r/prettymaps_/
- Online color picker: http://www.w3schools.com/colors/colors_picker.asp
- Adding captions in Matplotlib: https://matplotlib.org/stable/tutorials/text/text_intro.html
- Adding generic images in Matplotlib: https://stackoverflow.com/questions/3609585/how-to-insert-a-small-image-on-the-corner-of-a-plot-with-matplotlib
« Previous 1 2 3
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
AlmaLinux 10.0 Beta Released
The AlmaLinux OS Foundation has announced the availability of AlmaLinux 10.0 Beta ("Purple Lion") for all supported devices with significant changes.
-
Gnome 47.2 Now Available
Gnome 47.2 is now available for general use but don't expect much in the way of newness, as this is all about improvements and bug fixes.
-
Latest Cinnamon Desktop Releases with a Bold New Look
Just in time for the holidays, the developer of the Cinnamon desktop has shipped a new release to help spice up your eggnog with new features and a new look.
-
Armbian 24.11 Released with Expanded Hardware Support
If you've been waiting for Armbian to support OrangePi 5 Max and Radxa ROCK 5B+, the wait is over.
-
SUSE Renames Several Products for Better Name Recognition
SUSE has been a very powerful player in the European market, but it knows it must branch out to gain serious traction. Will a name change do the trick?
-
ESET Discovers New Linux Malware
WolfsBane is an all-in-one malware that has hit the Linux operating system and includes a dropper, a launcher, and a backdoor.
-
New Linux Kernel Patch Allows Forcing a CPU Mitigation
Even when CPU mitigations can consume precious CPU cycles, it might not be a bad idea to allow users to enable them, even if your machine isn't vulnerable.
-
Red Hat Enterprise Linux 9.5 Released
Notify your friends, loved ones, and colleagues that the latest version of RHEL is available with plenty of enhancements.
-
Linux Sees Massive Performance Increase from a Single Line of Code
With one line of code, Intel was able to increase the performance of the Linux kernel by 4,000 percent.
-
Fedora KDE Approved as an Official Spin
If you prefer the Plasma desktop environment and the Fedora distribution, you're in luck because there's now an official spin that is listed on the same level as the Fedora Workstation edition.