From 7c589f8852ed58bbc53cec4049614dc0d686a04e Mon Sep 17 00:00:00 2001 From: Aaron Epel Date: Wed, 1 Oct 2025 12:21:08 -0400 Subject: [PATCH 1/7] Refactored create_hexbin_mapbox to use *_map chart types instead of *_mapbox --- plotly/figure_factory/_hexbin_mapbox.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plotly/figure_factory/_hexbin_mapbox.py b/plotly/figure_factory/_hexbin_mapbox.py index c76352248b0..1eec4a775dd 100644 --- a/plotly/figure_factory/_hexbin_mapbox.py +++ b/plotly/figure_factory/_hexbin_mapbox.py @@ -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, scatter_mapbox +from plotly.express._chart_types import choropleth_map, scatter_map import narwhals.stable.v1 as nw import numpy as np @@ -446,7 +446,7 @@ def create_hexbin_mapbox( if range_color is None: range_color = [agg_data_frame["color"].min(), agg_data_frame["color"].max()] - fig = choropleth_mapbox( + fig = choropleth_map( data_frame=agg_data_frame.to_native(), geojson=geojson, locations="locations", @@ -462,7 +462,7 @@ def create_hexbin_mapbox( opacity=opacity, zoom=zoom, center=center, - mapbox_style=mapbox_style, + map_style=mapbox_style, title=title, template=template, width=width, @@ -470,7 +470,7 @@ def create_hexbin_mapbox( ) if show_original_data: - original_fig = scatter_mapbox( + original_fig = scatter_map( data_frame=( args["data_frame"].sort( by=args["animation_frame"], descending=False, nulls_last=True From b9a271d2d3012eadd4ed9d1b800573845093fe3f Mon Sep 17 00:00:00 2001 From: Aaron Epel Date: Wed, 1 Oct 2025 12:27:08 -0400 Subject: [PATCH 2/7] Updated create_hexbin_mapbox docstring --- plotly/figure_factory/_hexbin_mapbox.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plotly/figure_factory/_hexbin_mapbox.py b/plotly/figure_factory/_hexbin_mapbox.py index 1eec4a775dd..b8b32d75c86 100644 --- a/plotly/figure_factory/_hexbin_mapbox.py +++ b/plotly/figure_factory/_hexbin_mapbox.py @@ -521,6 +521,6 @@ def create_hexbin_mapbox( "bool", "Whether to show the original data on top of the hexbin aggregation.", ], - original_data_marker=["dict", "Scattermapbox marker options."], + original_data_marker=["dict", "Scattermap marker options."], ), ) From cd2d4ada0d192792f83217ff530aeb135f3d9759 Mon Sep 17 00:00:00 2001 From: Aaron Epel Date: 2025年10月21日 23:08:57 -0400 Subject: [PATCH 3/7] Renamed create_hexbin_mapbox to create_hexbin_map --- doc/apidoc/plotly.figure_factory.rst | 2 +- doc/python/hexbin-mapbox.md | 12 +++++----- plotly/figure_factory/__init__.py | 8 +++---- .../{_hexbin_mapbox.py => _hexbin_map.py} | 24 +++++++++++++++---- .../test_figure_factory.py | 20 ++++++++-------- 5 files changed, 40 insertions(+), 26 deletions(-) rename plotly/figure_factory/{_hexbin_mapbox.py => _hexbin_map.py} (96%) diff --git a/doc/apidoc/plotly.figure_factory.rst b/doc/apidoc/plotly.figure_factory.rst index 44f44b8d36c..be2a4613abf 100644 --- a/doc/apidoc/plotly.figure_factory.rst +++ b/doc/apidoc/plotly.figure_factory.rst @@ -18,7 +18,7 @@ create_distplot create_facet_grid create_gantt - create_hexbin_mapbox + create_hexbin_map create_ohlc create_quiver create_scatterplotmatrix diff --git a/doc/python/hexbin-mapbox.md b/doc/python/hexbin-mapbox.md index ed30f329774..4298a2d07be 100644 --- a/doc/python/hexbin-mapbox.md +++ b/doc/python/hexbin-mapbox.md @@ -46,7 +46,7 @@ import plotly.express as px px.set_mapbox_access_token(open(".mapbox_token").read()) df = px.data.carshare() -fig = ff.create_hexbin_mapbox( +fig = ff.create_hexbin_map( data_frame=df, lat="centroid_lat", lon="centroid_lon", nx_hexagon=10, opacity=0.9, labels={"color": "Point Count"}, ) @@ -63,7 +63,7 @@ import plotly.express as px px.set_mapbox_access_token(open(".mapbox_token").read()) df = px.data.carshare() -fig = ff.create_hexbin_mapbox( +fig = ff.create_hexbin_map( data_frame=df, lat="centroid_lat", lon="centroid_lon", nx_hexagon=10, opacity=0.5, labels={"color": "Point Count"}, min_count=1, @@ -80,7 +80,7 @@ import plotly.express as px px.set_mapbox_access_token(open(".mapbox_token").read()) df = px.data.carshare() -fig = ff.create_hexbin_mapbox( +fig = ff.create_hexbin_map( data_frame=df, lat="centroid_lat", lon="centroid_lon", nx_hexagon=10, opacity=0.5, labels={"color": "Point Count"}, min_count=1, color_continuous_scale="Viridis", @@ -100,7 +100,7 @@ import numpy as np px.set_mapbox_access_token(open(".mapbox_token").read()) df = px.data.carshare() -fig = ff.create_hexbin_mapbox( +fig = ff.create_hexbin_map( 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] @@ -118,7 +118,7 @@ import numpy as np px.set_mapbox_access_token(open(".mapbox_token").read()) df = px.data.carshare() -fig = ff.create_hexbin_mapbox( +fig = ff.create_hexbin_map( 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" @@ -150,7 +150,7 @@ frame = np.concatenate([ np.ones(N, int) * i for i in range(n_frames) ]) -fig = ff.create_hexbin_mapbox( +fig = ff.create_hexbin_map( lat=lat, lon=lon, nx_hexagon=15, animation_frame=frame, color_continuous_scale="Cividis", labels={"color": "Point Count", "frame": "Period"}, opacity=0.5, min_count=1, diff --git a/plotly/figure_factory/__init__.py b/plotly/figure_factory/__init__.py index 1919ca875f3..fa4648cd804 100644 --- a/plotly/figure_factory/__init__.py +++ b/plotly/figure_factory/__init__.py @@ -29,14 +29,14 @@ if optional_imports.get_module("pandas") is not None: from plotly.figure_factory._county_choropleth import create_choropleth - from plotly.figure_factory._hexbin_mapbox import create_hexbin_mapbox + from plotly.figure_factory._hexbin_map import create_hexbin_map else: def create_choropleth(*args, **kwargs): raise ImportError("Please install pandas to use `create_choropleth`") - def create_hexbin_mapbox(*args, **kwargs): - raise ImportError("Please install pandas to use `create_hexbin_mapbox`") + def create_hexbin_map(*args, **kwargs): + raise ImportError("Please install pandas to use `create_hexbin_map`") if optional_imports.get_module("skimage") is not None: @@ -57,7 +57,7 @@ def create_ternary_contour(*args, **kwargs): "create_distplot", "create_facet_grid", "create_gantt", - "create_hexbin_mapbox", + "create_hexbin_map", "create_ohlc", "create_quiver", "create_scatterplotmatrix", diff --git a/plotly/figure_factory/_hexbin_mapbox.py b/plotly/figure_factory/_hexbin_map.py similarity index 96% rename from plotly/figure_factory/_hexbin_mapbox.py rename to plotly/figure_factory/_hexbin_map.py index b8b32d75c86..1e9efeaf5d3 100644 --- a/plotly/figure_factory/_hexbin_mapbox.py +++ b/plotly/figure_factory/_hexbin_map.py @@ -3,6 +3,7 @@ from plotly.express._chart_types import choropleth_map, scatter_map import narwhals.stable.v1 as nw import numpy as np +import warnings def _project_latlon_to_wgs84(lat, lon): @@ -322,7 +323,7 @@ def _hexagons_to_geojson(hexagons_lats, hexagons_lons, ids=None): return dict(type="FeatureCollection", features=features) -def create_hexbin_mapbox( +def create_hexbin_map( data_frame=None, lat=None, lon=None, @@ -339,7 +340,7 @@ def create_hexbin_mapbox( opacity=None, zoom=None, center=None, - mapbox_style=None, + map_style=None, title=None, template=None, width=None, @@ -462,7 +463,7 @@ def create_hexbin_mapbox( opacity=opacity, zoom=zoom, center=center, - map_style=mapbox_style, + map_style=map_style, title=title, template=template, width=width, @@ -502,8 +503,8 @@ def create_hexbin_mapbox( return fig -create_hexbin_mapbox.__doc__ = make_docstring( - create_hexbin_mapbox, +create_hexbin_map.__doc__ = make_docstring( + create_hexbin_map, override_dict=dict( nx_hexagon=["int", "Number of hexagons (horizontally) to be created"], agg_func=[ @@ -524,3 +525,16 @@ def create_hexbin_mapbox( original_data_marker=["dict", "Scattermap marker options."], ), ) + +def create_hexbin_mapbox(*args, **kwargs): + warnings.warn( + "create_hexbin_mapbox() is deprecated and will be removed in the next major version. " + + "Please use create_hexbin_map() instead. " + + "Learn more at: https://plotly.com/python/mapbox-to-maplibre/", + stacklevel=2, + category=DeprecationWarning, + ) + if "mapbox_style" in kwargs: + kwargs["map_style"] = kwargs.pop("mapbox_style") + + return create_hexbin_map(*args, **kwargs) diff --git a/tests/test_optional/test_figure_factory/test_figure_factory.py b/tests/test_optional/test_figure_factory/test_figure_factory.py index f131bacdc5e..91aee8d4a00 100644 --- a/tests/test_optional/test_figure_factory/test_figure_factory.py +++ b/tests/test_optional/test_figure_factory/test_figure_factory.py @@ -4228,7 +4228,7 @@ def test_aggregation(self): lon = [1, 2, 3, 3, 0, 4, 5, 0, 5, 3, 1, 5, 4, 0, 1, 2, 5] color = np.ones(len(lat)) - fig1 = ff.create_hexbin_mapbox(lat=lat, lon=lon, nx_hexagon=1) + fig1 = ff.create_hexbin_map(lat=lat, lon=lon, nx_hexagon=1) actual_geojson = { "type": "FeatureCollection", @@ -4331,7 +4331,7 @@ def test_aggregation(self): self.compare_dict_values(fig1.data[0].geojson, actual_geojson) assert np.array_equal(fig1.data[0].z, actual_agg) - fig2 = ff.create_hexbin_mapbox( + fig2 = ff.create_hexbin_map( lat=lat, lon=lon, nx_hexagon=1, @@ -4341,7 +4341,7 @@ def test_aggregation(self): assert np.array_equal(fig2.data[0].z, np.ones(5)) - fig3 = ff.create_hexbin_mapbox( + fig3 = ff.create_hexbin_map( lat=np.random.randn(1000), lon=np.random.randn(1000), nx_hexagon=20, @@ -4364,8 +4364,8 @@ def test_build_dataframe(self): columns=["Latitude", "Longitude", "Metric", "Frame"], ) - fig1 = ff.create_hexbin_mapbox(lat=lat, lon=lon, nx_hexagon=nx_hexagon) - fig2 = ff.create_hexbin_mapbox( + fig1 = ff.create_hexbin_map(lat=lat, lon=lon, nx_hexagon=nx_hexagon) + fig2 = ff.create_hexbin_map( data_frame=df, lat="Latitude", lon="Longitude", nx_hexagon=nx_hexagon ) @@ -4375,7 +4375,7 @@ def test_build_dataframe(self): fig1.to_plotly_json()["data"][0], fig2.to_plotly_json()["data"][0] ) - fig3 = ff.create_hexbin_mapbox( + fig3 = ff.create_hexbin_map( lat=lat, lon=lon, nx_hexagon=nx_hexagon, @@ -4383,14 +4383,14 @@ def test_build_dataframe(self): agg_func=np.sum, min_count=0, ) - fig4 = ff.create_hexbin_mapbox( + fig4 = ff.create_hexbin_map( lat=lat, lon=lon, nx_hexagon=nx_hexagon, color=color, agg_func=np.sum, ) - fig5 = ff.create_hexbin_mapbox( + fig5 = ff.create_hexbin_map( data_frame=df, lat="Latitude", lon="Longitude", @@ -4406,7 +4406,7 @@ def test_build_dataframe(self): fig4.to_plotly_json()["data"][0], fig5.to_plotly_json()["data"][0] ) - fig6 = ff.create_hexbin_mapbox( + fig6 = ff.create_hexbin_map( data_frame=df, lat="Latitude", lon="Longitude", @@ -4416,7 +4416,7 @@ def test_build_dataframe(self): animation_frame="Frame", ) - fig7 = ff.create_hexbin_mapbox( + fig7 = ff.create_hexbin_map( lat=lat, lon=lon, nx_hexagon=nx_hexagon, From bd178f62d4de56e614111670b05d095df2d20f80 Mon Sep 17 00:00:00 2001 From: Aaron Epel Date: 2025年10月21日 23:14:45 -0400 Subject: [PATCH 4/7] Ruff formatting --- plotly/figure_factory/_hexbin_map.py | 36 ++++++++++++++++++---------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/plotly/figure_factory/_hexbin_map.py b/plotly/figure_factory/_hexbin_map.py index 1e9efeaf5d3..7be22e06050 100644 --- a/plotly/figure_factory/_hexbin_map.py +++ b/plotly/figure_factory/_hexbin_map.py @@ -30,9 +30,7 @@ def _getBoundsZoomLevel(lon_min, lon_max, lat_min, lat_max, mapDim): Source: https://stackoverflow.com/questions/6048975/google-maps-v3-how-to-calculate-the-zoom-level-for-a-given-bounds """ - scale = ( - 2 # adjustment to reflect MapBox base tiles are 512x512 vs. Google's 256x256 - ) + scale = 2 # adjustment to reflect MapBox base tiles are 512x512 vs. Google's 256x256 WORLD_DIM = {"height": 256 * scale, "width": 256 * scale} ZOOM_MAX = 18 @@ -295,7 +293,11 @@ def _compute_wgs84_hexbin( {"x1": centers[:, 0], "x2": centers[:, 1]}, native_namespace=native_namespace, ) - .select(hexagons_ids=nw.concat_str([nw.col("x1"), nw.col("x2")], separator=",")) + .select( + hexagons_ids=nw.concat_str( + [nw.col("x1"), nw.col("x2")], separator="," + ) + ) .get_column("hexagons_ids") ) @@ -423,7 +425,9 @@ def create_hexbin_map( lon=df.get_column(args["lon"]).to_numpy(), lat_range=lat_range, lon_range=lon_range, - color=df.get_column(args["color"]).to_numpy() if args["color"] else None, + color=df.get_column(args["color"]).to_numpy() + if args["color"] + else None, nx=nx_hexagon, agg_func=agg_func, min_count=min_count, @@ -440,12 +444,15 @@ def create_hexbin_map( ) ) - agg_data_frame = nw.concat(agg_data_frame_list, how="vertical").with_columns( - color=nw.col("color").cast(nw.Int64) - ) + agg_data_frame = nw.concat( + agg_data_frame_list, how="vertical" + ).with_columns(color=nw.col("color").cast(nw.Int64)) if range_color is None: - range_color = [agg_data_frame["color"].min(), agg_data_frame["color"].max()] + range_color = [ + agg_data_frame["color"].min(), + agg_data_frame["color"].max(), + ] fig = choropleth_map( data_frame=agg_data_frame.to_native(), @@ -453,7 +460,9 @@ def create_hexbin_map( locations="locations", color="color", hover_data={"color": True, "locations": False, "frame": False}, - animation_frame=("frame" if args["animation_frame"] is not None else None), + animation_frame=( + "frame" if args["animation_frame"] is not None else None + ), color_discrete_sequence=color_discrete_sequence, color_discrete_map=color_discrete_map, labels=labels, @@ -474,7 +483,9 @@ def create_hexbin_map( original_fig = scatter_map( data_frame=( args["data_frame"].sort( - by=args["animation_frame"], descending=False, nulls_last=True + by=args["animation_frame"], + descending=False, + nulls_last=True, ) if args["animation_frame"] is not None else args["data_frame"] @@ -526,6 +537,7 @@ def create_hexbin_map( ), ) + def create_hexbin_mapbox(*args, **kwargs): warnings.warn( "create_hexbin_mapbox() is deprecated and will be removed in the next major version. " @@ -537,4 +549,4 @@ def create_hexbin_mapbox(*args, **kwargs): if "mapbox_style" in kwargs: kwargs["map_style"] = kwargs.pop("mapbox_style") - return create_hexbin_map(*args, **kwargs) + return create_hexbin_map(*args, **kwargs) From dd3bd892a961af8be352c149fb9ab60d0becac6e Mon Sep 17 00:00:00 2001 From: Aaron Epel Date: 2025年10月21日 23:27:30 -0400 Subject: [PATCH 5/7] More ruff formatting --- plotly/figure_factory/_hexbin_map.py | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/plotly/figure_factory/_hexbin_map.py b/plotly/figure_factory/_hexbin_map.py index 7be22e06050..792cae5e238 100644 --- a/plotly/figure_factory/_hexbin_map.py +++ b/plotly/figure_factory/_hexbin_map.py @@ -30,7 +30,9 @@ def _getBoundsZoomLevel(lon_min, lon_max, lat_min, lat_max, mapDim): Source: https://stackoverflow.com/questions/6048975/google-maps-v3-how-to-calculate-the-zoom-level-for-a-given-bounds """ - scale = 2 # adjustment to reflect MapBox base tiles are 512x512 vs. Google's 256x256 + scale = ( + 2 # adjustment to reflect MapBox base tiles are 512x512 vs. Google's 256x256 + ) WORLD_DIM = {"height": 256 * scale, "width": 256 * scale} ZOOM_MAX = 18 @@ -293,11 +295,7 @@ def _compute_wgs84_hexbin( {"x1": centers[:, 0], "x2": centers[:, 1]}, native_namespace=native_namespace, ) - .select( - hexagons_ids=nw.concat_str( - [nw.col("x1"), nw.col("x2")], separator="," - ) - ) + .select(hexagons_ids=nw.concat_str([nw.col("x1"), nw.col("x2")], separator=",")) .get_column("hexagons_ids") ) @@ -425,9 +423,7 @@ def create_hexbin_map( lon=df.get_column(args["lon"]).to_numpy(), lat_range=lat_range, lon_range=lon_range, - color=df.get_column(args["color"]).to_numpy() - if args["color"] - else None, + color=df.get_column(args["color"]).to_numpy() if args["color"] else None, nx=nx_hexagon, agg_func=agg_func, min_count=min_count, @@ -444,9 +440,9 @@ def create_hexbin_map( ) ) - agg_data_frame = nw.concat( - agg_data_frame_list, how="vertical" - ).with_columns(color=nw.col("color").cast(nw.Int64)) + agg_data_frame = nw.concat(agg_data_frame_list, how="vertical").with_columns( + color=nw.col("color").cast(nw.Int64) + ) if range_color is None: range_color = [ @@ -460,9 +456,7 @@ def create_hexbin_map( locations="locations", color="color", hover_data={"color": True, "locations": False, "frame": False}, - animation_frame=( - "frame" if args["animation_frame"] is not None else None - ), + animation_frame=("frame" if args["animation_frame"] is not None else None), color_discrete_sequence=color_discrete_sequence, color_discrete_map=color_discrete_map, labels=labels, From 4d8fbc4bf4d95b392f46c79a7157eddaa17b04e7 Mon Sep 17 00:00:00 2001 From: Aaron Epel Date: 2025年10月22日 14:47:08 -0400 Subject: [PATCH 6/7] Updated figure factory init --- plotly/figure_factory/__init__.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/plotly/figure_factory/__init__.py b/plotly/figure_factory/__init__.py index fa4648cd804..c0ded37ca28 100644 --- a/plotly/figure_factory/__init__.py +++ b/plotly/figure_factory/__init__.py @@ -29,7 +29,10 @@ if optional_imports.get_module("pandas") is not None: from plotly.figure_factory._county_choropleth import create_choropleth - from plotly.figure_factory._hexbin_map import create_hexbin_map + from plotly.figure_factory._hexbin_map import ( + create_hexbin_map, + create_hexbin_mapbox, + ) else: def create_choropleth(*args, **kwargs): @@ -38,6 +41,9 @@ def create_choropleth(*args, **kwargs): def create_hexbin_map(*args, **kwargs): raise ImportError("Please install pandas to use `create_hexbin_map`") + def create_hexbin_mapbox(*args, **kwargs): + raise ImportError("Please install pandas to use `create_hexbin_mapbox`") + if optional_imports.get_module("skimage") is not None: from plotly.figure_factory._ternary_contour import create_ternary_contour @@ -58,6 +64,7 @@ def create_ternary_contour(*args, **kwargs): "create_facet_grid", "create_gantt", "create_hexbin_map", + "create_hexbin_mapbox", "create_ohlc", "create_quiver", "create_scatterplotmatrix", From 9773b5facabe0eb3abe92e8cb85e7c00c49bf42e Mon Sep 17 00:00:00 2001 From: Aaron Epel Date: 2025年10月22日 14:49:04 -0400 Subject: [PATCH 7/7] Removed Mapbox-related content from hexbin examples --- doc/python/hexbin-mapbox.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/doc/python/hexbin-mapbox.md b/doc/python/hexbin-mapbox.md index 4298a2d07be..079b337f952 100644 --- a/doc/python/hexbin-mapbox.md +++ b/doc/python/hexbin-mapbox.md @@ -37,13 +37,10 @@ jupyter: 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_map( @@ -60,7 +57,6 @@ fig.show() 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_map( @@ -77,7 +73,6 @@ fig.show() 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_map( @@ -97,7 +92,6 @@ import plotly.figure_factory as ff import plotly.express as px import numpy as np -px.set_mapbox_access_token(open(".mapbox_token").read()) df = px.data.carshare() fig = ff.create_hexbin_map( @@ -115,7 +109,6 @@ import plotly.figure_factory as ff import plotly.express as px import numpy as np -px.set_mapbox_access_token(open(".mapbox_token").read()) df = px.data.carshare() fig = ff.create_hexbin_map( @@ -133,7 +126,6 @@ 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

AltStyle によって変換されたページ (->オリジナル) /