Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0a1f48c

Browse files
committedJul 11, 2020
Option to display original data.
Documentation page.
1 parent 9c0b043 commit 0a1f48c

File tree

3 files changed

+208
-2
lines changed

3 files changed

+208
-2
lines changed
 

‎doc/python/figure-factories.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ The following types of plots are still difficult to create with Graph Objects or
4242
* [Annotated Heatmaps](/python/annotated-heatmap/)
4343
* [Dendrograms](/python/dendrogram/)
4444
* [Gantt Charts](/python/gantt/)
45+
* [Hexagonal Binning Mapbox](/python/hexbin-mapbox/)
4546
* [Quiver Plots](/python/quiver-plots/)
4647
* [Streamline Plots](/python/streamline-plots/)
4748
* [Tables](/python/figure-factory-table/)

‎doc/python/hexbin-mapbox.md

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
---
2+
jupyter:
3+
jupytext:
4+
notebook_metadata_filter: all
5+
text_representation:
6+
extension: .md
7+
format_name: markdown
8+
format_version: '1.2'
9+
jupytext_version: 1.5.1
10+
kernelspec:
11+
display_name: Python 3
12+
language: python
13+
name: python3
14+
language_info:
15+
codemirror_mode:
16+
name: ipython
17+
version: 3
18+
file_extension: .py
19+
mimetype: text/x-python
20+
name: python
21+
nbconvert_exporter: python
22+
pygments_lexer: ipython3
23+
version: 3.7.4
24+
plotly:
25+
description: How to make a map with Hexagonal Binning of data in Python with Plotly.
26+
display_as: scientific
27+
language: python
28+
layout: base
29+
name: Hexbin Mapbox
30+
order: 7
31+
page_type: u-guide
32+
permalink: python/hexbin-mapbox/
33+
redirect_from: python/hexbin-mapbox/
34+
thumbnail: thumbnail/hexbin_mapbox.jpg
35+
---
36+
37+
#### Simple Count Hexbin
38+
39+
This page details the use of a [figure factory](/python/figure-factories/). For more examples with Choropleth maps, see [this page](/python/choropleth-maps/).
40+
41+
In order to use mapbox styles that require a mapbox token, set the token with `plotly.express`. You can also use styles that do not require a mapbox token. See more information on [this page](/python/mapbox-layers/).
42+
43+
```python
44+
import plotly.figure_factory as ff
45+
import plotly.express as px
46+
47+
px.set_mapbox_access_token(open(".mapbox_token").read())
48+
df = px.data.carshare()
49+
50+
fig = ff.create_hexbin_mapbox(
51+
data_frame=df, lat="centroid_lat", lon="centroid_lon",
52+
nx_hexagon=10, opacity=0.9, labels={"color": "Point Count"},
53+
)
54+
fig.update_layout(margin=dict(b=0, t=0, l=0, r=0))
55+
fig.show()
56+
```
57+
58+
#### Count Hexbin with Minimum Count
59+
60+
```python
61+
import plotly.figure_factory as ff
62+
import plotly.express as px
63+
64+
px.set_mapbox_access_token(open(".mapbox_token").read())
65+
df = px.data.carshare()
66+
67+
fig = ff.create_hexbin_mapbox(
68+
data_frame=df, lat="centroid_lat", lon="centroid_lon",
69+
nx_hexagon=10, opacity=0.9, labels={"color": "Point Count"},
70+
min_count=1,
71+
)
72+
fig.show()
73+
```
74+
75+
#### Display the Underlying Data
76+
77+
```python
78+
import plotly.figure_factory as ff
79+
import plotly.express as px
80+
81+
px.set_mapbox_access_token(open(".mapbox_token").read())
82+
df = px.data.carshare()
83+
84+
fig = ff.create_hexbin_mapbox(
85+
data_frame=df, lat="centroid_lat", lon="centroid_lon",
86+
nx_hexagon=10, opacity=0.9, labels={"color": "Point Count"},
87+
min_count=1, color_continuous_scale="Viridis",
88+
show_original_data=True,
89+
original_data_marker=dict(size=4, opacity=0.6, color="deeppink")
90+
)
91+
fig.show()
92+
```
93+
94+
#### Compute the Mean Value per Hexbin
95+
96+
```python
97+
import plotly.figure_factory as ff
98+
import plotly.express as px
99+
100+
px.set_mapbox_access_token(open(".mapbox_token").read())
101+
df = px.data.carshare()
102+
103+
fig = ff.create_hexbin_mapbox(
104+
data_frame=df, lat="centroid_lat", lon="centroid_lon",
105+
nx_hexagon=10, opacity=0.9, labels={"color": "Average Peak Hour"},
106+
color="peak_hour", agg_func=np.mean, color_continuous_scale="Icefire", range_color=[0,23]
107+
)
108+
fig.show()
109+
```
110+
111+
#### Compute the Sum Value per Hexbin
112+
113+
```python
114+
import plotly.figure_factory as ff
115+
import plotly.express as px
116+
117+
px.set_mapbox_access_token(open(".mapbox_token").read())
118+
df = px.data.carshare()
119+
120+
fig = ff.create_hexbin_mapbox(
121+
data_frame=df, lat="centroid_lat", lon="centroid_lon",
122+
nx_hexagon=10, opacity=0.9, labels={"color": "Summed Car.Hours"},
123+
color="car_hours", agg_func=np.sum, color_continuous_scale="Magma"
124+
)
125+
fig.show()
126+
```
127+
128+
#### Hexbin with Animation
129+
130+
```python
131+
import plotly.figure_factory as ff
132+
import plotly.express as px
133+
import numpy as np
134+
135+
px.set_mapbox_access_token(open(".mapbox_token").read())
136+
np.random.seed(0)
137+
138+
N = 500
139+
n_frames = 12
140+
lat = np.concatenate([
141+
np.random.randn(N) * 0.5 + np.cos(i / n_frames * 2 * np.pi)
142+
for i in range(n_frames)
143+
])
144+
lon = np.concatenate([
145+
np.random.randn(N) * 0.5 + np.sin(i / n_frames * 2 * np.pi)
146+
for i in range(n_frames)
147+
])
148+
frame = np.concatenate([
149+
np.ones(N, int) * i for i in range(n_frames)
150+
])
151+
152+
fig = ff.create_hexbin_mapbox(
153+
lat=lat, lon=lon, nx_hexagon=15, animation_frame=frame,
154+
color_continuous_scale="Cividis", labels={"color": "Point Count", "frame": "Period"},
155+
show_original_data=True, original_data_marker=dict(opacity=0.6, size=4, color="deeppink")
156+
)
157+
fig.update_layout(margin=dict(b=0, t=0, l=0, r=0))
158+
fig.layout.sliders[0].pad.t=20
159+
fig.layout.updatemenus[0].pad.t=40
160+
fig.show()
161+
```
162+
163+
#### Reference
164+
165+
For more info on Plotly maps, see: https://plotly.com/python/maps.<br> For more info on using colorscales with Plotly see: https://plotly.com/python/heatmap-and-contour-colorscales/ <br>For more info on `ff.create_annotated_heatmap()`, see the [full function reference](https://plotly.com/python-api-reference/generated/plotly.figure_factory.create_hexbin_mapbox.html#plotly.figure_factory.create_hexbin_mapbox)
166+
167+
```python
168+
169+
```

‎packages/python/plotly/plotly/figure_factory/_hexbin_mapbox.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from plotly.express._core import build_dataframe
22
from plotly.express._doc import make_docstring
3-
from plotly.express._chart_types import choropleth_mapbox
3+
from plotly.express._chart_types import choropleth_mapbox, scatter_mapbox
44
import numpy as np
55
import pandas as pd
66

@@ -337,6 +337,8 @@ def create_hexbin_mapbox(
337337
width=None,
338338
height=None,
339339
min_count=None,
340+
show_original_data=False,
341+
original_data_marker=None,
340342
):
341343
"""
342344
Returns a figure aggregating scattered points into connected hexagons
@@ -412,7 +414,7 @@ def create_hexbin_mapbox(
412414
if range_color is None:
413415
range_color = [agg_data_frame["color"].min(), agg_data_frame["color"].max()]
414416

415-
return choropleth_mapbox(
417+
fig = choropleth_mapbox(
416418
data_frame=agg_data_frame,
417419
geojson=geojson,
418420
locations="locations",
@@ -435,6 +437,35 @@ def create_hexbin_mapbox(
435437
height=height,
436438
)
437439

440+
if show_original_data:
441+
original_fig = scatter_mapbox(
442+
data_frame=(
443+
args["data_frame"].sort_values(by=args["animation_frame"])
444+
if args["animation_frame"] is not None else
445+
args["data_frame"]
446+
),
447+
lat=args["lat"],
448+
lon=args["lon"],
449+
animation_frame=args["animation_frame"]
450+
)
451+
original_fig.data[0].hoverinfo = "skip"
452+
original_fig.data[0].hovertemplate = None
453+
original_fig.data[0].marker = original_data_marker
454+
455+
fig.add_trace(original_fig.data[0])
456+
457+
if args["animation_frame"] is not None:
458+
for i in range(len(original_fig.frames)):
459+
original_fig.frames[i].data[0].hoverinfo = "skip"
460+
original_fig.frames[i].data[0].hovertemplate = None
461+
original_fig.frames[i].data[0].marker = original_data_marker
462+
463+
fig.frames[i].data = [
464+
fig.frames[i].data[0], original_fig.frames[i].data[0],
465+
]
466+
467+
return fig
468+
438469

439470
create_hexbin_mapbox.__doc__ = make_docstring(
440471
create_hexbin_mapbox,
@@ -451,5 +482,10 @@ def create_hexbin_mapbox(
451482
"If None and color is not set, display all hexagons.",
452483
"If None and color is set, only display hexagons that contain points.",
453484
],
485+
show_original_data=[
486+
"bool",
487+
"Whether to show the original data on top of the hexbin aggregation."
488+
],
489+
original_data_marker=["dict", "Scattermapbox marker options."]
454490
),
455491
)

0 commit comments

Comments
 (0)
Please sign in to comment.