Skip to content

Commit

Permalink
Merge pull request #1937 from plotly/px_new_functions
Browse files Browse the repository at this point in the history
New mapbox functions in PX
  • Loading branch information
nicolaskruchten authored Dec 2, 2019
2 parents e3ef26a + 8ce78be commit 329beb9
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 31 deletions.
7 changes: 5 additions & 2 deletions packages/python/plotly/plotly/express/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"""
from __future__ import absolute_import
from plotly import optional_imports
from ._imshow import imshow

pd = optional_imports.get_module("pandas")
if pd is None:
Expand All @@ -12,7 +13,6 @@
Plotly express requires pandas to be installed."""
)


from ._chart_types import ( # noqa: F401
scatter,
scatter_3d,
Expand Down Expand Up @@ -44,9 +44,10 @@
treemap,
funnel,
funnel_area,
choropleth_mapbox,
density_mapbox,
)

from ._imshow import imshow

from ._core import ( # noqa: F401
set_mapbox_access_token,
Expand All @@ -66,6 +67,7 @@
"scatter_matrix",
"density_contour",
"density_heatmap",
"density_mapbox",
"line",
"line_3d",
"line_polar",
Expand All @@ -82,6 +84,7 @@
"strip",
"histogram",
"choropleth",
"choropleth_mapbox",
"pie",
"sunburst",
"treemap",
Expand Down
85 changes: 83 additions & 2 deletions packages/python/plotly/plotly/express/_chart_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -842,15 +842,13 @@ def choropleth(
hover_name=None,
hover_data=None,
custom_data=None,
size=None,
animation_frame=None,
animation_group=None,
category_orders={},
labels={},
color_continuous_scale=None,
range_color=None,
color_continuous_midpoint=None,
size_max=None,
projection=None,
scope=None,
center=None,
Expand Down Expand Up @@ -983,6 +981,8 @@ def scatter_mapbox(
opacity=None,
size_max=None,
zoom=8,
center=None,
mapbox_style=None,
title=None,
template=None,
width=None,
Expand All @@ -998,6 +998,85 @@ def scatter_mapbox(
scatter_mapbox.__doc__ = make_docstring(scatter_mapbox)


def choropleth_mapbox(
data_frame=None,
geojson=None,
locations=None,
color=None,
hover_name=None,
hover_data=None,
custom_data=None,
animation_frame=None,
animation_group=None,
category_orders={},
labels={},
color_continuous_scale=None,
range_color=None,
color_continuous_midpoint=None,
opacity=None,
zoom=8,
center=None,
mapbox_style=None,
title=None,
template=None,
width=None,
height=None,
):
"""
In a Mapbox choropleth map, each row of `data_frame` is represented by a
colored region on a Mapbox map.
"""
return make_figure(
args=locals(),
constructor=go.Choroplethmapbox,
trace_patch=dict(
geojson=geojson
if not hasattr(geojson, "__geo_interface__")
else geojson.__geo_interface__
),
)


choropleth_mapbox.__doc__ = make_docstring(choropleth_mapbox)


def density_mapbox(
data_frame=None,
lat=None,
lon=None,
z=None,
hover_name=None,
hover_data=None,
custom_data=None,
animation_frame=None,
animation_group=None,
category_orders={},
labels={},
color_continuous_scale=None,
range_color=None,
color_continuous_midpoint=None,
opacity=None,
zoom=8,
center=None,
mapbox_style=None,
radius=None,
title=None,
template=None,
width=None,
height=None,
):
"""
In a Mapbox density map, each row of `data_frame` contributes to the intensity of
the color of the region around the corresponding point on the map
"""
return make_figure(
args=locals(), constructor=go.Densitymapbox, trace_patch=dict(radius=radius)
)


density_mapbox.__doc__ = make_docstring(density_mapbox)


def line_mapbox(
data_frame=None,
lat=None,
Expand All @@ -1015,6 +1094,8 @@ def line_mapbox(
color_discrete_sequence=None,
color_discrete_map={},
zoom=8,
center=None,
mapbox_style=None,
title=None,
template=None,
width=None,
Expand Down
56 changes: 29 additions & 27 deletions packages/python/plotly/plotly/express/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ def make_trace_kwargs(args, trace_spec, g, mapping_labels, sizeref):
v_label_col = get_decorated_label(args, col, None)
mapping_labels[v_label_col] = "%%{customdata[%d]}" % (position)
elif k == "color":
if trace_spec.constructor == go.Choropleth:
if trace_spec.constructor in [go.Choropleth, go.Choroplethmapbox]:
result["z"] = g[v]
result["coloraxis"] = "coloraxis1"
mapping_labels[v_label] = "%{z}"
Expand Down Expand Up @@ -380,6 +380,8 @@ def configure_axes(args, constructor, fig, orders):
go.Scatterpolargl: configure_polar_axes,
go.Barpolar: configure_polar_axes,
go.Scattermapbox: configure_mapbox,
go.Choroplethmapbox: configure_mapbox,
go.Densitymapbox: configure_mapbox,
go.Scattergeo: configure_geo,
go.Choropleth: configure_geo,
}
Expand Down Expand Up @@ -502,13 +504,11 @@ def configure_cartesian_axes(args, fig, orders):


def configure_ternary_axes(args, fig, orders):
fig.update(
layout=dict(
ternary=dict(
aaxis=dict(title=get_label(args, args["a"])),
baxis=dict(title=get_label(args, args["b"])),
caxis=dict(title=get_label(args, args["c"])),
)
fig.update_layout(
ternary=dict(
aaxis=dict(title=get_label(args, args["a"])),
baxis=dict(title=get_label(args, args["b"])),
caxis=dict(title=get_label(args, args["c"])),
)
)

Expand Down Expand Up @@ -562,28 +562,28 @@ def configure_3d_axes(args, fig, orders):


def configure_mapbox(args, fig, orders):
fig.update(
layout=dict(
mapbox=dict(
accesstoken=MAPBOX_TOKEN,
center=dict(
lat=args["data_frame"][args["lat"]].mean(),
lon=args["data_frame"][args["lon"]].mean(),
),
zoom=args["zoom"],
)
center = args["center"]
if not center and "lat" in args and "lon" in args:
center = dict(
lat=args["data_frame"][args["lat"]].mean(),
lon=args["data_frame"][args["lon"]].mean(),
)
fig.update_layout(
mapbox=dict(
accesstoken=MAPBOX_TOKEN,
center=center,
zoom=args["zoom"],
style=args["mapbox_style"],
)
)


def configure_geo(args, fig, orders):
fig.update(
layout=dict(
geo=dict(
center=args["center"],
scope=args["scope"],
projection=dict(type=args["projection"]),
)
fig.update_layout(
geo=dict(
center=args["center"],
scope=args["scope"],
projection=dict(type=args["projection"]),
)
)

Expand Down Expand Up @@ -1083,7 +1083,7 @@ def infer_config(args, constructor, trace_patch):
# Compute final trace patch
trace_patch = trace_patch.copy()

if constructor == go.Histogram2d:
if constructor in [go.Histogram2d, go.Densitymapbox]:
show_colorbar = True
trace_patch["coloraxis"] = "coloraxis1"

Expand Down Expand Up @@ -1221,6 +1221,8 @@ def make_figure(args, constructor, trace_patch={}, layout_patch={}):
go.Parcats,
go.Parcoords,
go.Choropleth,
go.Choroplethmapbox,
go.Densitymapbox,
go.Histogram2d,
go.Sunburst,
go.Treemap,
Expand Down Expand Up @@ -1321,7 +1323,7 @@ def make_figure(args, constructor, trace_patch={}, layout_patch={}):
)
layout_patch = layout_patch.copy()
if show_colorbar:
colorvar = "z" if constructor == go.Histogram2d else "color"
colorvar = "z" if constructor in [go.Histogram2d, go.Densitymapbox] else "color"
range_color = args["range_color"] or [None, None]

colorscale_validator = ColorscaleValidator("colorscale", "make_figure")
Expand Down
11 changes: 11 additions & 0 deletions packages/python/plotly/plotly/express/_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@
colref_desc,
"Values from this column or array_like are used to assign mark sizes.",
],
radius=["int (default is 30)", "Sets the radius of influence of each point.",],
hover_name=[
colref_type,
colref_desc,
Expand Down Expand Up @@ -445,6 +446,12 @@
"Dict keys are `'lat'` and `'lon'`",
"Sets the center point of the map.",
],
mapbox_style=[
"str (default `'basic'`, needs Mapbox API token)",
"Identifier of base map style, some of which require a Mapbox API token to be set using `plotly.express.set_mapbox_access_token()`.",
"Allowed values which do not require a Mapbox API token are `'open-street-map'`, `'white-bg'`, `'carto-positron'`, `'carto-darkmatter'`, `'stamen-terrain'`, `'stamen-toner'`, `'stamen-watercolor'`.",
"Allowed values which do require a Mapbox API token are `'basic'`, `'streets'`, `'outdoors'`, `'light'`, `'dark'`, `'satellite'`, `'satellite-streets'`.",
],
points=[
"str or boolean (default `'outliers'`)",
"One of `'outliers'`, `'suspectedoutliers'`, `'all'`, or `False`.",
Expand All @@ -456,6 +463,10 @@
],
box=["boolean (default `False`)", "If `True`, boxes are drawn inside the violins."],
notched=["boolean (default `False`)", "If `True`, boxes are drawn with notches."],
geojson=[
"GeoJSON-formatted dict",
"Must contain a Polygon feature collection, with IDs, which are references from `locations`.",
],
cumulative=[
"boolean (default `False`)",
"If `True`, histogram values are cumulative.",
Expand Down
Binary file not shown.
70 changes: 70 additions & 0 deletions test/percy/plotly-express.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,37 @@

import plotly.express as px

sample_geojson = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": "the_polygon",
"geometry": {
"type": "Polygon",
"coordinates": [
[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0]]
],
},
}
],
}
fig = px.choropleth_mapbox(
geojson=sample_geojson, locations=["the_polygon"], color=[10], zoom=6,
)
fig.write_html(os.path.join(dir_name, "choropleth_mapbox.html"), auto_play=False)

import plotly.express as px

carshare = px.data.carshare()
fig = px.density_mapbox(
carshare, lat="centroid_lat", lon="centroid_lon", z="peak_hour",
)
fig.write_html(os.path.join(dir_name, "density_mapbox.html"), auto_play=False)

import plotly.express as px


gapminder = px.data.gapminder()
fig = px.scatter_geo(
gapminder,
Expand Down Expand Up @@ -470,3 +501,42 @@
range_color=[20, 80],
)
fig.write_html(os.path.join(dir_name, "choropleth.html"), auto_play=False)

import plotly.express as px

tips = px.data.tips()
fig = px.pie(tips, names="smoker", values="total_bill")
fig.write_html(os.path.join(dir_name, "pie.html"), auto_play=False)

import plotly.express as px

tips = px.data.tips()
fig = px.funnel_area(tips, names="smoker", values="total_bill")
fig.write_html(os.path.join(dir_name, "funnel_area.html"), auto_play=False)

import plotly.express as px

fig = px.treemap(
names=["Eve", "Cain", "Seth", "Enos", "Noam", "Abel", "Awan", "Enoch", "Azura"],
parents=["", "Eve", "Eve", "Seth", "Seth", "Eve", "Eve", "Awan", "Eve"],
values=[10, 14, 12, 10, 2, 6, 6, 4, 4],
)
fig.write_html(os.path.join(dir_name, "treemap.html"), auto_play=False)


import plotly.express as px

fig = px.sunburst(
names=["Eve", "Cain", "Seth", "Enos", "Noam", "Abel", "Awan", "Enoch", "Azura"],
parents=["", "Eve", "Eve", "Seth", "Seth", "Eve", "Eve", "Awan", "Eve"],
values=[10, 14, 12, 10, 2, 6, 6, 4, 4],
)
fig.write_html(os.path.join(dir_name, "sunburst.html"), auto_play=False)


import plotly.express as px

fig = px.funnel(
y=["first", "second", "first", "second"], x=[3, 1, 4, 2], color=["A", "A", "B", "B"]
)
fig.write_html(os.path.join(dir_name, "funnel.html"), auto_play=False)

0 comments on commit 329beb9

Please sign in to comment.