8000 Finishing up Hexbin Mapbox PR by nicolaskruchten · Pull Request #2638 · plotly/plotly.py · GitHub
[go: up one dir, main page]

Skip to content

Finishing up Hexbin Mapbox PR #2638

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Jul 14, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Option to display original data.
Documentation page.
  • Loading branch information
RenaudLN committed Jul 11, 2020
commit 0a1f48cf9e82d6b7e7f63e9f2fdf8d82b743e548
1 change: 1 addition & 0 deletions doc/python/figure-factories.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ The following types of plots are still difficult to create with Graph Objects or
* [Annotated Heatmaps](/python/annotated-heatmap/)
* [Dendrograms](/python/dendrogram/)
* [Gantt Charts](/python/gantt/)
* [Hexagonal Binning Mapbox](/python/hexbin-mapbox/)
* [Quiver Plots](/python/quiver-plots/)
* [Streamline Plots](/python/streamline-plots/)
* [Tables](/python/figure-factory-table/)
Expand Down
169 changes: 169 additions & 0 deletions doc/python/hexbin-mapbox.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
---
jupyter:
jupytext:
notebook_metadata_filter: all
text_representation:
extension: .md
format_name: markdown
format_version: '1.2'
jupytext_version: 1.5.1
kernelspec:
display_name: Python 3
language: python
name: python3
language_info:
codemirror_mode:
name: ipython
version: 3
file_extension: .py
mimetype: text/x-python
name: python
nbconvert_exporter: python
pygments_lexer: ipython3
version: 3.7.4
plotly:
description: How to make a map with Hexagonal Binning of data in Python with Plotly.
display_as: scientific
language: python
layout: base
name: Hexbin Mapbox
order: 7
page_type: u-guide
permalink: python/hexbin-mapbox/
redirect_from: python/hexbin-mapbox/
thumbnail: thumbnail/hexbin_mapbox.jpg
---

#### Simple Count Hexbin

This page details the use of a [figure factory](/python/figure-factories/). For more examples with Choropleth maps, see [this page](/python/choropleth-maps/).

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/).

```python
import plotly.figure_factory as ff
import plotly.express as px

px.set_mapbox_access_token(open(".mapbox_token").read())
df = px.data.carshare()

fig = ff.create_hexbin_mapbox(
data_frame=df, lat="centroid_lat", lon="centroid_lon",
nx_hexagon=10, opacity=0.9, labels={"color": "Point Count"},
)
fig.update_layout(margin=dict(b=0, t=0, l=0, r=0))
fig.show()
```

#### Count Hexbin with Minimum Count

```python
import plotly.figure_factory as ff
import plotly.express as px

px.set_mapbox_access_token(open(".mapbox_token").read())
df = px.data.carshare()

fig = ff.create_hexbin_mapbox(
data_frame=df, lat="centroid_lat", lon="centroid_lon",
nx_hexagon=10, opacity=0.9, labels={"color": "Point Count"},
min_count=1,
)
fig.show()
```

#### Display the Underlying Data

```python
import plotly.figure_factory as ff
import plotly.express as px

px.set_mapbox_access_token(open(".mapbox_token").read())
df = px.data.carshare()

fig = ff.create_hexbin_mapbox(
data_frame=df, lat="centroid_lat", lon="centroid_lon",
nx_hexagon=10, opacity=0.9, labels={"color": "Point Count"},
min_count=1, color_continuous_scale="Viridis",
show_original_data=True,
original_data_marker=dict(size=4, opacity=0.6, color="deeppink")
)
fig.show()
```

#### Compute the Mean Value per Hexbin

```python
import plotly.figure_factory as ff
import plotly.express as px

px.set_mapbox_access_token(open(".mapbox_token").read())
df = px.data.carshare()

fig = ff.create_hexbin_mapbox(
data_frame=df, lat="centroid_lat", lon="centroid_lon",
nx_hexagon=10, opacity=0.9, labels={"color": "Average Peak Hour"},
color="peak_hour", agg_func=np.mean, color_continuous_scale="Icefire", range_color=[0,23]
)
fig.show()
```

#### Compute the Sum Value per Hexbin

```python
import plotly.figure_factory as ff
import plotly.express as px

px.set_mapbox_access_token(open(".mapbox_token").read())
df = px.data.carshare()

fig = ff.create_hexbin_mapbox(
data_frame=df, lat="centroid_lat", lon="centroid_lon",
nx_hexagon=10, opacity=0.9, labels={"color": "Summed Car.Hours"},
color="car_hours", agg_func=np.sum, color_continuous_scale="Magma"
)
fig.show()
```

#### Hexbin with Animation

```python
import plotly.figure_factory as ff
import plotly.express as px
import numpy as np

px.set_mapbox_access_token(open(".mapbox_token").read())
np.random.seed(0)

N = 500
n_frames = 12
lat = np.concatenate([
np.random.randn(N) * 0.5 + np.cos(i / n_frames * 2 * np.pi)
for i in range(n_frames)
])
lon = np.concatenate([
< 8000 span class='blob-code-inner blob-code-marker ' data-code-marker="+"> np.random.randn(N) * 0.5 + np.sin(i / n_frames * 2 * np.pi)
for i in range(n_frames)
])
frame = np.concatenate([
np.ones(N, int) * i for i in range(n_frames)
])

fig = ff.create_hexbin_mapbox(
lat=lat, lon=lon, nx_hexagon=15, animation_frame=frame,
color_continuous_scale="Cividis", labels={"color": "Point Count", "frame": "Period"},
show_original_data=True, original_data_marker=dict(opacity=0.6, size=4, color="deeppink")
)
fig.update_layout(margin=dict(b=0, t=0, l=0, r=0))
fig.layout.sliders[0].pad.t=20
fig.layout.updatemenus[0].pad.t=40
fig.show()
```

#### Reference

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)

```python

```
40 changes: 38 additions & 2 deletions packages/python/plotly/plotly/figure_factory/_hexbin_mapbox.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from plotly.express._core import build_dataframe
from plotly.express._doc import make_docstring
from plotly.express._chart_types import choropleth_mapbox
from plotly.express._chart_types import choropleth_mapbox, scatter_mapbox
import numpy as np
import pandas as pd

Expand Down Expand Up @@ -337,6 +337,8 @@ def create_hexbin_mapbox(
width=None,
height=None,
min_count=None,
show_original_data=False,
original_data_marker=None,
):
"""
Returns a figure aggregating scattered points into connected hexagons
Expand Down Expand Up @@ -412,7 +414,7 @@ def create_hexbin_mapbox(
if range_color is None:
range_color = [agg_data_frame["color"].min(), agg_data_frame["color"].max()]

return choropleth_mapbox(
fig = choropleth_mapbox(
data_frame=agg_data_frame,
geojson=geojson,
locations="locations",
Expand All @@ -435,6 +437,35 @@ def create_hexbin_mapbox(
height=height,
)

if show_original_data:
original_fig = scatter_mapbox(
data_frame=(
args["data_frame"].sort_values(by=args["animation_frame"])
if args["animation_frame"] is not None else
args["data_frame"]
),
lat=args["lat"],
lon=args["lon"],
animation_frame=args["animation_frame"]
)
original_fig.data[0].hoverinfo = "skip"
original_fig.data[0].hovertemplate = None
original_fig.data[0].marker = original_data_marker

fig.add_trace(original_fig.data[0])

if args["animation_frame"] is not None:
for i in range(len(original_fig.frames)):
original_fig.frames[i].data[0].hoverinfo = "skip"
original_fig.frames[i].data[0].hovertemplate = None
original_fig.frames[i].data[0].marker = original_data_marker

fig.frames[i].data = [
fig.frames[i].data[0], original_fig.frames[i].data[0],
]

return fig


create_hexbin_mapbox.__doc__ = make_docstring(
create_hexbin_mapbox,
Expand All @@ -451,5 +482,10 @@ def create_hexbin_mapbox(
"If None and color is not set, display all hexagons.",
"If None and color is set, only display hexagons that contain points.",
],
show_original_data=[
"bool",
"Whether to show the original data on top of the hexbin aggregation."
],
original_data_marker=["dict", "Scattermapbox marker options."]
),
)
0