gmaps
gmaps copied to clipboard
Ability to add a legend to marker and symbol layers?
Hi Pascal, I am using your great package on a data science project. I need to use symbol_layer to add crimes from different years. I couldn't find a way to show a legend to indicate what color is from what year. Is there a way to do it? Thanks.
Here is the pseudocode if you will:
- Loop over crime coordinates from 10 year data
- Add a symbol layer per year with a different color and end loop
- Add a legend to indicate different years.
- Show the figure.
Hi Pascal, I am using your great package on a data science project
Great! Thanks for the feedback.
At the moment, there is no canned way to add a legend to a symbol layer (this would make a great addition, PRs welcome!). You are probably best off drawing your own using jupyter widgets. Since gmaps maps are themselves Jupyter widgets, you can use them as building blocks for more complex visualisations.
For instance:
import random
from matplotlib.cm import tab10 # Use the matplotlib tab10 colormap
from matplotlib.colors import to_hex
import ipywidgets as widgets
gmaps.configure(api_key='...')
def gen_random_locations(npoints):
"""
Generate `npoints` random locations in the US
"""
latitudes = [random.uniform(32.7, 48.6) for _ in range(npoints)]
longitudes = [random.uniform(-124.5, -77.0) for _ in range(npoints)]
return list(zip(latitudes, longitudes))
# These are the 10 years that make up your data
years = [1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006]
assert len(years) == 10
data = {year: gen_random_locations(10) for year in years}
colors = {year: to_hex(tab10(iyear)) for iyear, year in enumerate(years)} # generate a colour for each year
# Some CSS hackery to draw a circle of that color next to the year
legend_template = '<span style="color: {color}; font-size: 2em; vertical-align: bottom;">●</span> {year}'
def draw_map_with_legend():
figure = gmaps.figure()
legend_entries = []
for iyear, year in enumerate(years):
locations = data[year]
color = colors[year]
points_layer = gmaps.symbol_layer(
locations,
fill_color=color,
stroke_color=color,
fill_opacity=0.7,
stroke_opacity=0.7
)
figure.add_layer(points_layer)
legend_entries.append(legend_template.format(color=color, year=year))
legend = widgets.HBox(
[widgets.HTML(legend_entry) for legend_entry in legend_entries],
layout=widgets.Layout(width='100%', justify_content='space-between')
)
return widgets.VBox([figure, legend])
draw_map_with_legend()
Note the following:
- we use the HBox and VBox widgets to stack widgets (like maps and legend entries).
- we use a matplotlib colormap to get some colors that go well together. I chose the
tab10at random. See the matplotlib docs for other color maps. You can also just choose arbitrary colors, obviously.
For anyone interested in implementing this.
One avenue to consider is using the feature built into google maps. Alternatively, we add a legend box to the figure that can be populated by layers, much like the toolbar box.
Thank you. I am quite new to this. I will try your code and learn more about the widgets in jupyter.