Folium Multiple map overlays - python

I'm fairly new to folium so this might be a bit noobish but I'm currently trying to plot several heatmaps of different data-points and add the ability to switch between the heatmaps all on the same plot. So for example I have such:
# The base map
hmap = folium.Map(location=[38.908111, -77.008871], tiles="Stamen Terrain", zoom_start=12)
# And each layer
# Homicide
HeatMap(list(zip(crime_homicide.LATITUDE.values, crime_homicide.LONGITUDE.values))).add_to(folium.FeatureGroup(name='Homicides').add_to(hmap))
# Robbery
HeatMap(list(zip(crime_robbery.LATITUDE.values, crime_robbery.LONGITUDE.values))).add_to(folium.FeatureGroup(name='Robbery').add_to(hmap))
# Assault
HeatMap(list(zip(crime_assault.LATITUDE.values, crime_assault.LONGITUDE.values))).add_to(folium.FeatureGroup(name='Assault').add_to(hmap))
folium.LayerControl(collapsed=False).add_to(hmap)
folium.GeoJson(dc_shape).add_to(hmap)
I tried using folium's FeatureGroup functionality but it looks like thats only specific markers as opposed to whole maps. Is there a way to switch between different maps if they're all heatmaps?

Your code seems fine.
Try this -
hmap.add_child
Or you can try heatmapwithtime as well, specifying different metrics which you can adjust in realtime to see different heatmaps.
But,FeatureGroup() will not seem to work with HeatMapWithTime and adding layers directly to the heatmap results in multiple time sliders on the side when there should be only one (common) time slider for all added layers.
So if you want to have a single control you'll have to put all your data in a single geojson and use that.
Why do you add a feature group? If you want to be able to select which instance of HeatMapWithTime you want to display, you can add both add them to the map, and they should both turn up in layer control.
m = Map()
HeatMapWithTime(data1).add_to(m)
HeatMapWithTime(data2).add_to(m)
FYI, a feature group is meant to group items and display them together. The items themselves don't get added to the map directly. For example:
fg = FeatureGroup().add_to(m)
fg.add_child(Item1)
fg.add_child(Item2)
Also this is the link, might help you :)
https://python-visualization.github.io/folium/plugins.html

Related

Folium - Label each area in a GeoJSON

I have a GeoJSON file that contains country/empire borders in the year 1800. I am trying to depict this using Folium. I would like to have the name of each country/empire to be displayed (text) within each country/empire region in the map (basically the same as what is shown on "normal" present-day maps, but I can't just overlay this over present-day maps because the borders have changed over time). The GeoJSON file has a field that contains the name of each respective country/border, but I don't know how to display this on the map.
I do not want this to be a tooltip / popup. Instead, I want the text displayed in the base map, viewable without hovering your mouse over the map or clicking on anything.
I have seen some similar questions, and the responses are essentially to use a DivIcon. But this seems like a clunky solution and not very clean when dealing with a large map and many, many labels.
Is there a good way to display this? I looked in the Folium documentation and didn't see any arguments in the GeoJson class that seems like it would do this. (For example, it would be nice to tell Folium to automatically add 'region' labels, and to use a given field as the source of the labels).
Thanks!

Mapping bokeh RangeSlider output into different labels

I have RangeSlider defined as follows,
slider = RangeSlider(start=0, end=5, value=(0,1), step=1, title="Time")
Is there a way to change the output of the slider so that instead of getting the values 0 to 5, I am able to 'map' these values into some other labels. For instance, whenever the range is 0...4, I get instead t0...t4.
I have not been able to find any information in the bokeh documentation to do this. I am just wondering whether it is at all possible.
I would appear that this is possible but the answer is not simple, and requires going deep into bokeh and javascript. I have found a some mention of this possibility in this video (see video # min 25:30) which lead me to this file in the bokeh repo.

How can I arrange two faceted side-by-side charts horizontally in Altair?

Altair offers lovely feature to facet charts using facet method. For example, following dataset visualizes nicely:
print(df[['Year', 'Profile', 'Saison', 'Pos']].to_csv())
,Year,Profile,Saison,Pos
0,2017,6.0,Sommer,VL
1,2017,6.0,Winter,VL
13,2017,6.0,Winter,HL
12,2017,6.0,Sommer,HL
18,2017,6.0,Sommer,HR
6,2017,6.0,Sommer,VR
7,2017,6.0,Winter,VR
19,2017,6.0,Winter,HR
14,2018,5.5,Winter,HL
8,2018,5.5,Winter,VR
15,2018,5.5,Sommer,HL
20,2018,4.3,Winter,HR
21,2018,5.0,Sommer,HR
3,2018,5.5,Sommer,VL
2,2018,6.2,Winter,VL
9,2018,4.5,Sommer,VR
17,2019,4.5,Sommer,HL
11,2019,4.2,Sommer,VR
22,2019,3.5,Winter,HR
10,2019,5.28,Winter,VR
5,2019,4.6,Sommer,VL
4,2019,4.9,Winter,VL
16,2019,4.0,Winter,HL
23,2019,4.5,Sommer,HR
with the following command:
alt.Chart(df).mark_bar().encode(x='Year:O', y='Profile:Q').facet(row='Saison:N', column='Pos:N')
But, as you can seem I have still a lot of place horizontally and would like to use it by rearranging Winter plot right next to the Summer plot:
I understand that I already used column grid to facet over attribute Pos, but visually for me Winter and Sommer plots are two separate plots (just like here), which I'd like to place side by side.
I tried to create two different charts in the same cell and using html emit them side by side, but in Jupyter environment there is a limitation on just one Altair/Vega plot per cell.
Is there any method I can use to arrange these charts horizontally?
In Altair, there is no good way to do this, because faceted charts cannot be nested according to the Vega-Lite schema. However, the Vega-Lite renderer actually does handle this in some cases, despite it technically being disallowed by the schema.
So you can hack it by doing something like this:
chart = alt.Chart(df).mark_bar().encode(
x='Year:O',
y='Profile:Q'
).facet('Saison:N')
spec = alt.FacetChart(
data=df,
spec=chart,
facet=alt.Facet('Pos:N')
).to_json(validate=False)
print(spec)
The resulting spec can be pasted by hand into http://vega.github.io/editor to reveal this (vega editor link):
You'll even notice that the vega editor flags parts of the spec as invalid. This is admittedly not the most satisfying answer, but it sort of works.
Hopefully in the future the Vega-Lite schema will add actual support for nested facets, so they can be used more directly from Altair.

How to make an interactive image plot (with bokeh?)

I would like to take raster (say a JPG) cut it in subregions and associate each reagion to a row in a pandas dataframe, so that the image can be visualized according to some filters on the data. I see this is pretty standard using bokeh in python, but I do not find tutorial on how to prepare the raster for this. All explanation somehow use premade data such as the counties of texas example in bokeh ...
So, what should I do to my custom image to transform it into something can be used with bokeh to make an interactive map?

Add Label Annotations on Axes

I currently annotate my charts with the last value of each series by adding a Label and supplying my the name of corresponding range it's plotted on:
Label(
...
x=data.index.max(),
y=data.loc[data.index.max(), 'my_col'],
y_range_name='my_range'
...
)
Which gives me:
How do I move the labels so they are positioned on their respective axis?
Example:
Please note that my labels' y-positioning is off, so I need some help with that aspect too. I've tried tweaking the y_offset but this has not yielded any consistently good results.
My data are always numerical time series.
As of Bokeh 1.2 there is no built-in annotation or glyph that will display outside the central plot area. There is an open issue on GitHub that this is similar to that you can follow or comment on. For the time being, something like this would require making a custom extension

Categories