Skip to content

Commit

Permalink
Merge pull request #4726 from plotly/maplibre-tests_with-px
Browse files Browse the repository at this point in the history
Add new `map` options to `px` and update plotly.js/master at 056799dfc705a4533935ae3169cc94d35bc44830
  • Loading branch information
LiamConnors authored Aug 29, 2024
2 parents 2bd7dc6 + 4fc6d81 commit 24730c3
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 9 deletions.
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

0 comments on commit 24730c3

Please sign in to comment.