Skip to content
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

Add new map options to px and update plotly.js/master at 056799dfc705a4533935ae3169cc94d35bc44830 #4726

Merged
merged 6 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 4 additions & 0 deletions doc/apidoc/plotly.express.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ plotly's high-level API for rapid figure generation. ::
scatter_3d
scatter_polar
scatter_ternary
scatter_map
scatter_mapbox
scatter_geo
line
line_3d
line_polar
line_ternary
line_map
line_mapbox
line_geo
area
Expand All @@ -45,9 +47,11 @@ plotly's high-level API for rapid figure generation. ::
parallel_coordinates
parallel_categories
choropleth
choropleth_map
choropleth_mapbox
density_contour
density_heatmap
density_map
density_mapbox
imshow
set_mapbox_access_token
Expand Down
7 changes: 4 additions & 3 deletions packages/python/plotly/plotly/_subplots.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# little differently.
import collections

_single_subplot_types = {"scene", "geo", "polar", "ternary", "mapbox"}
_single_subplot_types = {"scene", "geo", "polar", "ternary", "map", "mapbox"}
_subplot_types = set.union(_single_subplot_types, {"xy", "domain"})

# For most subplot types, a trace is associated with a particular subplot
Expand All @@ -20,7 +20,7 @@
# the trace property is just named `subplot`. For example setting
# the `scatterpolar.subplot` property to `polar3` associates the scatterpolar
# trace with the third polar subplot in the figure
_subplot_prop_named_subplot = {"polar", "ternary", "mapbox"}
_subplot_prop_named_subplot = {"polar", "ternary", "map", "mapbox"}


# Named tuple to hold an xaxis/yaxis pair that represent a single subplot
Expand Down Expand Up @@ -150,7 +150,8 @@ def make_subplots(
- 'scene': 3D Cartesian subplot for scatter3d, cone, etc.
- 'polar': Polar subplot for scatterpolar, barpolar, etc.
- 'ternary': Ternary subplot for scatterternary
- 'mapbox': Mapbox subplot for scattermapbox
- 'map': Map subplot for scattermap, choroplethmap and densitymap
- 'mapbox': Mapbox subplot for scattermapbox, choroplethmapbox and densitymapbox
- 'domain': Subplot type for traces that are individually
positioned. pie, parcoords, parcats, etc.
- trace type: A trace type which will be used to determine
Expand Down
8 changes: 8 additions & 0 deletions packages/python/plotly/plotly/express/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
scatter_3d,
scatter_polar,
scatter_ternary,
scatter_map,
scatter_mapbox,
scatter_geo,
line,
line_3d,
line_polar,
line_ternary,
line_map,
line_mapbox,
line_geo,
area,
Expand All @@ -46,7 +48,9 @@
icicle,
funnel,
funnel_area,
choropleth_map,
choropleth_mapbox,
density_map,
density_mapbox,
)

Expand All @@ -67,16 +71,19 @@
"scatter_3d",
"scatter_polar",
"scatter_ternary",
"scatter_map",
"scatter_mapbox",
"scatter_geo",
"scatter_matrix",
"density_contour",
"density_heatmap",
"density_map",
"density_mapbox",
"line",
"line_3d",
"line_polar",
"line_ternary",
"line_map",
"line_mapbox",
"line_geo",
"parallel_coordinates",
Expand All @@ -91,6 +98,7 @@
"histogram",
"ecdf",
"choropleth",
"choropleth_map",
"choropleth_mapbox",
"pie",
"sunburst",
Expand Down
147 changes: 147 additions & 0 deletions packages/python/plotly/plotly/express/_chart_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,153 @@ def line_geo(
line_geo.__doc__ = make_docstring(line_geo)


def scatter_map(
data_frame=None,
lat=None,
lon=None,
color=None,
text=None,
hover_name=None,
hover_data=None,
custom_data=None,
size=None,
animation_frame=None,
animation_group=None,
category_orders=None,
labels=None,
color_discrete_sequence=None,
color_discrete_map=None,
color_continuous_scale=None,
range_color=None,
color_continuous_midpoint=None,
opacity=None,
size_max=None,
zoom=8,
center=None,
map_style=None,
title=None,
template=None,
width=None,
height=None,
) -> go.Figure:
"""
In a scatter map, each row of `data_frame` is represented by a
symbol mark on the map.
"""
return make_figure(args=locals(), constructor=go.Scattermap)


scatter_map.__doc__ = make_docstring(scatter_map)


def choropleth_map(
data_frame=None,
geojson=None,
featureidkey=None,
locations=None,
color=None,
hover_name=None,
hover_data=None,
custom_data=None,
animation_frame=None,
animation_group=None,
category_orders=None,
labels=None,
color_discrete_sequence=None,
color_discrete_map=None,
color_continuous_scale=None,
range_color=None,
color_continuous_midpoint=None,
opacity=None,
zoom=8,
center=None,
map_style=None,
title=None,
template=None,
width=None,
height=None,
) -> go.Figure:
"""
In a choropleth map, each row of `data_frame` is represented by a
colored region on the map.
"""
return make_figure(args=locals(), constructor=go.Choroplethmap)


choropleth_map.__doc__ = make_docstring(choropleth_map)


def density_map(
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=None,
labels=None,
color_continuous_scale=None,
range_color=None,
color_continuous_midpoint=None,
opacity=None,
zoom=8,
center=None,
map_style=None,
radius=None,
title=None,
template=None,
width=None,
height=None,
) -> go.Figure:
"""
In a 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.Densitymap, trace_patch=dict(radius=radius)
)


density_map.__doc__ = make_docstring(density_map)


def line_map(
data_frame=None,
lat=None,
lon=None,
color=None,
text=None,
hover_name=None,
hover_data=None,
custom_data=None,
line_group=None,
animation_frame=None,
animation_group=None,
category_orders=None,
labels=None,
color_discrete_sequence=None,
color_discrete_map=None,
zoom=8,
center=None,
map_style=None,
title=None,
template=None,
width=None,
height=None,
) -> go.Figure:
"""
In a line map, each row of `data_frame` is represented as
vertex of a polyline mark on the map.
"""
return make_figure(args=locals(), constructor=go.Scattermap)


line_map.__doc__ = make_docstring(line_map)


def scatter_mapbox(
data_frame=None,
lat=None,
Expand Down
46 changes: 40 additions & 6 deletions packages/python/plotly/plotly/express/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,11 @@ def make_trace_kwargs(args, trace_spec, trace_data, mapping_labels, sizeref):
# as a list of row lists, which is what we want
trace_patch["customdata"] = trace_data[customdata_cols]
elif attr_name == "color":
if trace_spec.constructor in [go.Choropleth, go.Choroplethmapbox]:
if trace_spec.constructor in [
go.Choropleth,
go.Choroplethmap,
go.Choroplethmapbox,
]:
trace_patch["z"] = trace_data[attr_value]
trace_patch["coloraxis"] = "coloraxis1"
mapping_labels[attr_label] = "%{z}"
Expand Down Expand Up @@ -532,6 +536,9 @@ def configure_axes(args, constructor, fig, orders):
go.Scatterpolar: configure_polar_axes,
go.Scatterpolargl: configure_polar_axes,
go.Barpolar: configure_polar_axes,
go.Scattermap: configure_map,
go.Choroplethmap: configure_map,
go.Densitymap: configure_map,
go.Scattermapbox: configure_mapbox,
go.Choroplethmapbox: configure_mapbox,
go.Densitymapbox: configure_mapbox,
Expand Down Expand Up @@ -739,6 +746,20 @@ def configure_mapbox(args, fig, orders):
)


def configure_map(args, fig, orders):
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_maps(
center=center,
zoom=args["zoom"],
style=args["map_style"],
)


def configure_geo(args, fig, orders):
fig.update_geos(
center=args["center"],
Expand Down Expand Up @@ -1911,15 +1932,21 @@ def infer_config(args, constructor, trace_patch, layout_patch):
else:
trace_patch["texttemplate"] = "%{" + letter + ":" + args["text_auto"] + "}"

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

if "opacity" in args:
if args["opacity"] is None:
if "barmode" in args and args["barmode"] == "overlay":
trace_patch["marker"] = dict(opacity=0.5)
elif constructor in [go.Densitymapbox, go.Pie, go.Funnel, go.Funnelarea]:
elif constructor in [
go.Densitymap,
go.Densitymapbox,
go.Pie,
go.Funnel,
go.Funnelarea,
]:
trace_patch["opacity"] = args["opacity"]
else:
trace_patch["marker"] = dict(opacity=args["opacity"])
Expand All @@ -1937,7 +1964,7 @@ def infer_config(args, constructor, trace_patch, layout_patch):
modes.add("lines")
trace_patch["mode"] = "+".join(sorted(modes))
elif constructor != go.Splom and (
"symbol" in args or constructor == go.Scattermapbox
"symbol" in args or constructor in [go.Scattermap, go.Scattermapbox]
):
trace_patch["mode"] = "markers" + ("+text" if args["text"] else "")

Expand Down Expand Up @@ -2154,7 +2181,9 @@ def make_figure(args, constructor, trace_patch=None, layout_patch=None):
go.Parcats,
go.Parcoords,
go.Choropleth,
go.Choroplethmap,
go.Choroplethmapbox,
go.Densitymap,
go.Densitymapbox,
go.Histogram2d,
go.Sunburst,
Expand Down Expand Up @@ -2198,7 +2227,8 @@ def make_figure(args, constructor, trace_patch=None, layout_patch=None):
):
trace.update(marker=dict(color=m.val_map[val]))
elif (
trace_spec.constructor in [go.Choropleth, go.Choroplethmapbox]
trace_spec.constructor
in [go.Choropleth, go.Choroplethmap, go.Choroplethmapbox]
and m.variable == "color"
):
trace.update(
Expand Down Expand Up @@ -2281,7 +2311,11 @@ def make_figure(args, constructor, trace_patch=None, layout_patch=None):
)

if show_colorbar:
colorvar = "z" if constructor in [go.Histogram2d, go.Densitymapbox] else "color"
colorvar = (
"z"
if constructor in [go.Histogram2d, go.Densitymap, go.Densitymapbox]
else "color"
)
range_color = args["range_color"] or [None, None]

colorscale_validator = ColorscaleValidator("colorscale", "make_figure")
Expand Down
5 changes: 5 additions & 0 deletions packages/python/plotly/plotly/express/_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,11 @@
"Dict keys are `'lat'` and `'lon'`",
"Sets the center point of the map.",
],
map_style=[
"str (default `'basic'`)",
"Identifier of base map style.",
"Allowed values are `'basic'`, `'carto-darkmatter'`, `'carto-darkmatter-nolabels'`, `'carto-positron'`, `'carto-positron-nolabels'`, `'carto-voyager'`, `'carto-voyager-nolabels'`, `'dark'`, `'light'`, `'open-street-map'`, `'outdoors'`, `'satellite'`, `'satellite-streets'`, `'streets'`, `'white-bg'`.",
],
mapbox_style=[
"str (default `'basic'`, needs Mapbox API token)",
"Identifier of base map style, some of which require a Mapbox or Stadia Maps API token to be set using `plotly.express.set_mapbox_access_token()`.",
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/subplots.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ def make_subplots(
- 'scene': 3D Cartesian subplot for scatter3d, cone, etc.
- 'polar': Polar subplot for scatterpolar, barpolar, etc.
- 'ternary': Ternary subplot for scatterternary
- 'map': Map subplot for scattermap
- 'mapbox': Mapbox subplot for scattermapbox
- 'domain': Subplot type for traces that are individually
positioned. pie, parcoords, parcats, etc.
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/templategen/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
("scattergl", "marker"),
("scatter3d", "line"),
("scatter3d", "marker"),
("scattermap", "marker"),
("scattermapbox", "marker"),
("scatterternary", "marker"),
("scattercarpet", "marker"),
Expand Down