If you haven't already, it's first good to check out the first notebook in the series: Finding Coordinates.
After this tutorial, you will be able to create a map that looks something like this one (code at the end):
This notebook will look much worse on a PDF!! Maps are shifted to the upper left so that content at least appears, however background boxes and some icons do not display properly when saved in this way.
Code is instructions written in a programming language. That means instructions that are written in a way that a computer can understand and follow. This notebook contains code that can be run, so you can look at the code and see what it does in the same place! Code can be run from code cells, which look like this:
Code cells can contain text or code. If some text starts with this sign:
# it is a comment, or a note for a human. The cell right below this sentence is a code cell that contains a comment.
# This is a code cell that contains a comment!
When you run a code cell, a number will appear in between the brackets. Often some output will be made by running the cell. This will usually be displayed below the cell.
To run a cell click within the grey box and press the
Run button on the toolbar. You can see the
Run button in the image below.
If you change something in a cell you need to run it again (press
Run another time) to update the output.
When something doesn't run correctly an error will appear. That looks like this:
Hint: think of the order of operations!
A comment can also be used to prevent some code from running. This can be useful for testing out things!
2-(2+1) # this gives more information but the code still runs
# 2-(2+1) # now the whole line is a comment (no output)
For this tutorial, we will use the Python as the programming language. Python is a common language used for writing code. A Python library is a collection of code that someone else has already written that is intended to be used over and over again! We will use the Folium library to help map things. It's really useful because you won't have to build a whole system from scratch in order to create a cool map and display it on the screen!
First we need to tell Python that we are using the Folium library. We do that using the
import command, where we type the name of the library in the form that Python is expecting (Python is expecting it to be lowercase) after the word
Run this next cell to tell Python to use the Folium library. Here we are just telling Python to use the library we want, so there is no output.
Writing Python code is like writing out a recipe. There are some parts that need to be written very specifically in a certain form and others parts that are more flexible. Try to follow the examples closely until you learn what parts are flexible. If you have a space or comma in the wrong place or a missing bracket (
}) or parenthesis
) Python will likely get mad and you will get an error!
Creating a map with Folium is like building a sandwich. To create any map, you must have two pieces: we can call them the top of the bun and the bottom of the bun. Like so: This diagram shows the simplest example of a map that you can make. You can see map this creates by running the next cell.
my_map = folium.Map([41.8233, -87.4158]) my_map
What do you see? Where is this? Take a moment to describe different things you can see on this map and what you can do with it.
I see quite a bit already! There is a background, with **blue** water for the lake and rivers, **tan** for the land, roads in **red**, **orange**, and **grey**, and parks in **green**. I see names of cities (like Chicago), neighborhoods, and interstates. I see symbols for airports ✈.
Also you can interact with the map! You can zoom in and out by clicking the
- buttons and drag the map with your mouse to move from side to side. If you want to go back to the starting position, run the cell again!
All of this with 2 lines of code - not bad!
This basic part of the map is called the base map. Everything else you add to the map will go on top of this.
Lets break it down (these section introduces common ways to talk about each of the pieces):
my_map- this is a Python variable name, which is a fancy way of saying the name that you call your map. Every time you need to refer to your map you need to use the same name written the same way (i.e. lower case with an underscore between the two words).
=- this is the way in Python you link some data, in this case your actual map, to a variable name. You can say you assigned a unique version of a map object to the variable named
folium.Map(- this is part of the recipe that you can't change and have it still work. This tells the Folium library that you want to make a map.
[41.88,-87.66]- these should look familiar - these are the coordinate number pairs you saw in the 1st notebook. This tells the library where you want your map. (Do you remember what each number refers to?) They must be in the square brackets (
) because that's how Folium wants it!
)- this tells Folium that you have given it everything you wanted to make the first map. If you delete this Folium will be angry.
my_map- this tells Python to actually show your map! Note that if you delete this your map will still be created but you won't see anything. That's why you should have this on your last line for every map you map in this tutorial.
And that's it!
However, it isn't a very interesting map yet is it? This sandwich needs some fillings!
What I'm calling fillings here is actual content that you can add to your map. While an actual sandwich can only be so tall before you can't eat it, our maps can have as many fillings as you want and you can mix even filling types (we'll explore that later).
In the next cell we have a basic map with one filling: a marker. Think of a marker as a pin that you can stick in a certain point on a map. Before you run the next cell, try to imagine what you think the marker might look like.
my_map = folium.Map([41.8233, -87.4158]) folium.Marker([41.88, -87.66]).add_to(my_map) my_map
The new pieces here are
.add_to(my_map). Folium needs the
.add_to() function exactly as written to link your marker to your map. You link it by putting the variable name for your map, in this case
my_map in the parenthesis after
Coming back to the map as a sandwich, note that the top of the bun is thicker than the bottom and the filling section is the thickest. Here the top can expand a little bit, the fillings can expand a lot, but for now the bottom will always stay the same size.
Let's start with the top bun. The next cell is similar to our original maps, however more information is specified in the top bun line using the following keywords:
zoom_start. Basically everything that you can use to customize the base map needs to go between the parentheses (
()) that appear after
folium.Map. This tells Folium that these extra pieces of information go with the base map itself and not another part of the map.
Each keyword group inside of the parentheses contains three pieces: a
keyword, an equals sign (
=), and some information. If the keyword group is not at the end of the list, you need a comma (
,) after the group to tell Python that another keyword group will come next. Note that keywords are case sensitive and need to be spelled exactly as they are shown here (including any underscores
_) to work!
In the next example, we can change the background by changing the
tiles keyword value. Possible background choices you can use with the
tiles keyword include: 'OpenStreetMap' (the default option), 'Stamen Terrain', 'Stamen Toner', 'Stamen Watercolor', 'CartoDB positron', and 'CartoDB dark_matter'. Again, these must be written exactly as they are here. Experiment to find your favorite!
zoom_start sets the initial map zoom to a different value. Change the green number after
zoom_start - when you make the number bigger what happens when you re run the cell? What do you think would happen if you made the number smaller?
Can you tell what the
control_scale keyword does? Try changing
False for this keyword (make sure only the first letter is uppercase). If it is written correctly it will show up as **bold and green**.
my_map = folium.Map(location=[41.8772, -87.6102], tiles='CartoDB positron', zoom_start=15, control_scale=True) my_map
Now we pause really quick. The next section is going to involve many different locations. In the previous notebook on Finding Coordinates we discussed how to find coordinates using Google Maps. Now that we know about Folium, let me show you another way!
Run the next cell. In the map in the next cell, click on the map to see a window pop up with the coordinates displayed in the window like in the image below. You can select the text with your mouse and copy and paste to easily find coordinates for things you want to map in the next section!
lat_long_map = folium.Map(location=[41.8746, -87.6240], zoom_start=4) lat_long_map.add_child(folium.LatLngPopup()) lat_long_map
At this point in the tutorial you may want to look to see what different types of kewords and extra things Folium has that you can use! A master list can be found here: https://python-visualization.github.io/folium/modules.html . You can search for the name of what you want to edit. Note that things like
folium.Marker() are called classes.
Note that this is written for people who code and it's OK if it is a little difficult to understand at first. Using what you have learned you should be able to try out new combinations.
On to more filling, what you've been waiting for! You have already seen a marker. We will now show you more things you can do with a marker, and introduce some other things you can add to your map.
Each of these items needs to be placed at a specific location, so keep your coordinates in mind as you go on!
Look at the code before you run this next cell. What do you think the new lines might do?
my_map = folium.Map(location=[41.8772, -87.6102], zoom_start=15) folium.map.Marker(location=[41.881832,-87.623177], popup="Hello, I'm a popup", tooltip='This is a tooltip').add_to(my_map) my_map
We've added a few more keywords!
popupcontrols the text that you see when you click on the marker.
tooltipcontains the text that you see when you hover your mouse over the marker.
Try both of these actions if you haven't yet!
Note that the red text in the code cell is called a string of text or a text string. We've seen these before with the map
tiles keyword content. Strings need to be surrounded by either single or double quotation marks (
"). If your text you want to enter contains one of these quotation marks, you need to use the other mark to surround the string. If you use both, you can use a set of three quotation marks (you can see an example below).
You can also store a text string as a variable just like you have been storing your map in a variable with the name
my_map. I've stored some text in a variable called
new_tooltip_text in the next cell. Remember you have to run the cell for Python to capture your code and be able to use the variable later.
new_tooltip_text = """The example's code says:<br>"this is<br>a tooltip"! """
In the next map, instead of typing the text for the
tooltip keyword, we typed the variable name for the text string I just created in the previous cell.
<br> is an example of an HTML tag (learn more about HTML). Make a wild guess: How do you think the
<br> tags will be displayed in the tooltip?
my_map = folium.Map(location=[41.8772, -87.6102], zoom_start=15) folium.map.Marker(location=[41.881832,-87.623177], tooltip=new_tooltip_text).add_to(my_map) my_map
<br> HTML tag tells Folium to switch to the next line at the point that the
<br> tag is entered. You can use HTML to format some of the text you display in your map, including in the popup window.
We can also change the icon used for the marker, as in the cell below. Note here that we are providing a
folium.Icon() to the
icon keyword. This is a specific format you need to use to provide more information to Folium about how you want the icon displayed. You need to use this format because Folium has already put together code as a shortcut so you don't have to do a ton of work to change the icon around.
You can add multiple markers by copying and pasting the whole
folium.map.Marker(...).add_to(my_map) code and placing the second one after the first. Use this same technique to add multiple of other types of fillings.
Remember the markers are filling so your bottom bun (
my_map) must always be the last line!
from folium import plugins # this line is needed for BeautifyIcon my_map = folium.Map(location=[41.8772, -87.6102], zoom_start=15) folium.map.Marker(location=[41.880932,-87.617777], icon=folium.Icon(color='red', icon='cloud', angle=45), tooltip="red cloud" ).add_to(my_map) # The coordinates for this marker are slightly changed! folium.map.Marker(location=[41.882832,-87.619177], icon=folium.Icon(color='orange', icon='cloud', angle=20), tooltip="orange cloud" ).add_to(my_map) # We can use a slightly different icon 'recipe' to add text or numbers to an icon folium.map.Marker(location=[41.880832,-87.620577], icon=folium.plugins.BeautifyIcon(border_color='blue', text_color='blue', number='A', icon_shape='marker'), tooltip="blue A" ).add_to(my_map) folium.map.Marker(location=[41.884332,-87.620577], icon=folium.plugins.BeautifyIcon(border_color='Green', text_color='green', number=1, icon_shape='marker'), tooltip="green 1" ).add_to(my_map) my_map
You may want to add some text to your map! This is useful for labeling things!
You can add text using
folium.DivIcon() with the
icon keyword instead of
folium.Icon(). This allows you to display HTML directly on your map.
div is an HTML tag. This type of HTML tag has two parts, the first part,
<div>, that marks the beginning of the tag, and the second part
</div> that marks the end. The text in the middle between the two tags can be thought of as the contents of the tag. The
<br> tag didn't need two parts because a line break can not contain anything.
It can be easier to work with HTML if you use three quotation marks to surround the text string. That way Python won't get mad if you divide the text in multiple lines.
my_map = folium.Map(location=[41.8772, -87.6102], tiles='CartoDB positron', zoom_start=15) folium.Marker(location=[41.881832,-87.620177], icon=folium.DivIcon( icon_size=(100, 100), html='''<div>This is some text on the map</div>''') ).add_to(my_map) my_map
The text is there but it can be hard to see on a regular map background.
This next example is slightly more complicated. The extra values in the
style are used to control more aspects of how the text is displayed.
style is a keyword in HTML that provides more information about the
Note that these keyword groups are slightly different than the ones we've seen before. Instead of parenthesis, all the keyword groups are contained in double quotation marks. So the entire keyword container structure looks like
style=" ". In the container, each keyword group contains a keyword, such as
font-size, a colon (
:), and more information. Here keyword groups are separated by a semi-colon (
my_map = folium.Map(location=[41.8772, -87.6102], zoom_start=15) folium.Marker(location=[41.881832,-87.623177], icon=folium.DivIcon( icon_size=(180, 20), html='''<div style=" font-size: 18pt; font-family: serif; color: black; text-align: center; background-color: white;"> This is some text on the map </div>''') ).add_to(my_map) my_map
You can use
folium.raster_layers.ImageOverlay() to add an image.
The hardest part is telling Folium where the corners of your image are. The
bounds keyword expects a set of two coordinates like this:
[[lat_min, lon_min], [lat_max, lon_max]], where
lat stands for latitude and
lon stands for longitude. In practice though it's fairly flexible.
You will probably need to try different coordinates for the
bounds keyword to place the image where you want it.
opacity keyword can be used to make the image more or less transparent (see-through).
Note that if you move the map the image moves too so that it stays in the same spot on the map.
Also note that having too many images can make your map load slowly!
my_map = folium.Map(location=[41.8772, -87.6102], zoom_start=15) folium.raster_layers.ImageOverlay( image='map photos/pumpkins.png', bounds=[[41.885, -87.620], [41.880, -87.628]], opacity=0.6).add_to(my_map) my_map