diff --git a/doc/python/dumbbell-plots.md b/doc/python/dumbbell-plots.md new file mode 100644 index 00000000000..f3ff1f8dc51 --- /dev/null +++ b/doc/python/dumbbell-plots.md @@ -0,0 +1,176 @@ +--- +jupyter: + jupytext: + notebook_metadata_filter: all + text_representation: + extension: .md + format_name: markdown + format_version: '1.3' + jupytext_version: 1.14.1 + kernelspec: + display_name: Python 3 (ipykernel) + 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.8.0 + plotly: + description: How to create dumbbell plots in Python with Plotly. + display_as: basic + language: python + layout: base + name: Dumbbell Plots + order: 19 + page_type: example_index + permalink: python/dumbbell-plots/ + thumbnail: thumbnail/dumbbell-plot.jpg +--- + +## Basic Dumbbell Plot + + +Dumbbell plots are useful for demonstrating change between two sets of data points, for example, the population change for a selection of countries for two different years + +In this example, we compare life expectancy in 1952 with life expectancy in 2002 for countries in Europe. + +```python +import plotly.graph_objects as go +from plotly import data + +import pandas as pd + +df = data.gapminder() +df = df.loc[(df.continent == "Europe") & (df.year.isin([1952, 2002]))] + +countries = ( + df.loc[(df.continent == "Europe") & (df.year.isin([2002]))] + .sort_values(by=["lifeExp"], ascending=True)["country"] + .unique() +) + +data = {"x": [], "y": [], "colors": [], "years": []} + +for country in countries: + data["x"].extend( + [ + df.loc[(df.year == 1952) & (df.country == country)]["lifeExp"].values[0], + df.loc[(df.year == 2002) & (df.country == country)]["lifeExp"].values[0], + None, + ] + ) + data["y"].extend([country, country, None]), + data["colors"].extend(["green", "blue", "brown"]), + data["years"].extend(["1952", "2002", None]) + +fig = go.Figure( + data=[ + go.Scatter( + x=data["x"], + y=data["y"], + mode="lines", + marker=dict( + color="grey", + ), + ), + go.Scatter( + x=data["x"], + y=data["y"], + mode="markers+text", + marker=dict( + color=data["colors"], + size=10, + ), + hovertemplate="""Country: %{y}
Life Expectancy: %{x}
""", + ), + ] +) + +fig.update_layout( + title="Life Expectancy in Europe: 1952 and 2002", + width=1000, + height=1000, + showlegend=False, +) + +fig.show() + +``` + +## Dumbbell Plot with Arrow Markers + +*Note: The `arrow`, `angleref`, and `standoff` properties used on the `marker` in this example are new in 5.11* + +In this example, we add arrow markers to the plot. The first trace adds the lines connecting the data points and arrow markers. +The second trace adds circle markers. On the first trace, we use `standoff=8` to position the arrow marker back from the data point. +For the arrow marker to point directly at the circle marker, this value should be half the circle marker size. + +```python +import pandas as pd +import plotly.graph_objects as go +from plotly import data + +df = data.gapminder() +df = df.loc[(df.continent == "Europe") & (df.year.isin([1952, 2002]))] + +countries = ( + df.loc[(df.continent == "Europe") & (df.year.isin([2002]))] + .sort_values(by=["lifeExp"], ascending=True)["country"] + .unique() +) + +data = {"x": [], "y": [], "colors": [], "years": []} + +for country in countries: + data["x"].extend( + [ + df.loc[(df.year == 1952) & (df.country == country)]["lifeExp"].values[0], + df.loc[(df.year == 2002) & (df.country == country)]["lifeExp"].values[0], + None, + ] + ) + data["y"].extend([country, country, None]), + data["colors"].extend(["silver", "lightskyblue", "white"]), + data["years"].extend(["1952", "2002", None]) + +fig = go.Figure( + data=[ + go.Scatter( + x=data["x"], + y=data["y"], + mode="markers+lines", + marker=dict( + symbol="arrow", color="black", size=16, angleref="previous", standoff=8 + ), + ), + go.Scatter( + x=data["x"], + y=data["y"], + text=data["years"], + mode="markers", + marker=dict( + color=data["colors"], + size=16, + ), + hovertemplate="""Country: %{y}
Life Expectancy: %{x}
Year: %{text}
""", + ), + ] +) + +fig.update_layout( + title="Life Expectancy in Europe: 1952 and 2002", + width=1000, + height=1000, + showlegend=False, +) + + +fig.show() + +``` diff --git a/doc/python/legend.md b/doc/python/legend.md index a83ab1e7c45..7fafadd107a 100644 --- a/doc/python/legend.md +++ b/doc/python/legend.md @@ -8,7 +8,7 @@ jupyter: format_version: '1.3' jupytext_version: 1.14.1 kernelspec: - display_name: Python 3 + display_name: Python 3 (ipykernel) language: python name: python3 language_info: @@ -20,7 +20,7 @@ jupyter: name: python nbconvert_exporter: python pygments_lexer: ipython3 - version: 3.8.8 + version: 3.8.0 plotly: description: How to configure and style the legend in Plotly with Python. display_as: file_settings @@ -189,6 +189,31 @@ fig.update_layout(legend=dict( fig.show() ``` +#### Horizontal Legend Entry Width + +*New in 5.11* + +Set the width of hozitonal legend entries by setting `entrywidth`. Here we set it to `70` pixels. Pixels is the default unit for `entrywidth`, but you can set it to be a fraction of the plot width using `entrywidthmode='fraction`. + +```python +import plotly.express as px + +df = px.data.gapminder().query("year==2007") +fig = px.scatter(df, x="gdpPercap", y="lifeExp", color="continent", + size="pop", size_max=45, log_x=True) + +fig.update_layout(legend=dict( + orientation="h", + entrywidth=70, + yanchor="bottom", + y=1.02, + xanchor="right", + x=1 +)) + +fig.show() +``` + #### Styling Legends Legends support many styling options. diff --git a/doc/python/mapbox-layers.md b/doc/python/mapbox-layers.md index 70cbaad4d7d..be8d238bef4 100644 --- a/doc/python/mapbox-layers.md +++ b/doc/python/mapbox-layers.md @@ -5,10 +5,10 @@ jupyter: text_representation: extension: .md format_name: markdown - format_version: '1.2' - jupytext_version: 1.3.1 + format_version: '1.3' + jupytext_version: 1.14.1 kernelspec: - display_name: Python 3 + display_name: Python 3 (ipykernel) language: python name: python3 language_info: @@ -20,7 +20,7 @@ jupyter: name: python nbconvert_exporter: python pygments_lexer: ipython3 - version: 3.6.8 + version: 3.8.0 plotly: description: How to make Mapbox maps in Python with various base layers, with or without needing a Mapbox Access token. @@ -192,6 +192,37 @@ fig.show() See the example in the [plotly and datashader tutorial](/python/datashader). + +#### Setting Map Bounds + +*New in 5.11* + +Set bounds for a map to specify an area outside which a user interacting with the map can't pan or zoom. Here we set a maximum longitude of `-180`, a minimum longitude of `-50`, a maximum latitude of `90`, and a minimum latitude of `20`. + +```python +import plotly.express as px +import pandas as pd + +us_cities = pd.read_csv( + "https://raw.githubusercontent.com/plotly/datasets/master/us-cities-top-1k.csv" +) + +fig = px.scatter_mapbox( + us_cities, + lat="lat", + lon="lon", + hover_name="City", + hover_data=["State", "Population"], + color_discrete_sequence=["fuchsia"], + zoom=3, + height=300, +) +fig.update_layout(mapbox_style="open-street-map") +fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0}) +fig.update_layout(mapbox_bounds={"west": -180, "east": -50, "south": 20, "north": 90}) +fig.show() +``` + #### Reference See https://plotly.com/python/reference/layout/mapbox/ for more information and options! diff --git a/doc/python/marker-style.md b/doc/python/marker-style.md index e51e564bb3a..128b22d04c5 100644 --- a/doc/python/marker-style.md +++ b/doc/python/marker-style.md @@ -8,7 +8,7 @@ jupyter: format_version: '1.3' jupytext_version: 1.14.1 kernelspec: - display_name: Python 3 + display_name: Python 3 (ipykernel) language: python name: python3 language_info: @@ -20,7 +20,7 @@ jupyter: name: python nbconvert_exporter: python pygments_lexer: ipython3 - version: 3.8.8 + version: 3.8.0 plotly: description: How to style markers in Python with Plotly. display_as: file_settings @@ -332,6 +332,8 @@ Each basic symbol is also represented by a number. Adding 100 to that number is In the following figure, hover over a symbol to see its name or number. Set the `marker_symbol` attribute equal to that name or number to change the marker symbol in your figure. +> The `arrow-wide` and `arrow` marker symbols are new in 5.11 + ```python import plotly.graph_objects as go from plotly.validators.scatter.marker import SymbolValidator @@ -357,6 +359,158 @@ fig.show() ``` +### Using a Custom Marker + +To use a custom marker, set the `symbol` on the `marker`. Here we set it to `diamond`. + + +```python +import plotly.express as px + +df = px.data.iris() +fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species") + +fig.update_traces( + marker=dict(size=8, symbol="diamond", line=dict(width=2, color="DarkSlateGrey")), + selector=dict(mode="markers"), +) +fig.show() + +``` + +### Setting Marker Angles + + +*New in 5.11* + +Change the angle of markers by setting `angle`. Here we set the angle on the `arrow` markers to `45`. + +```python +import plotly.express as px + +df = px.data.iris() +fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species") + +fig.update_traces( + marker=dict( + size=12, symbol="arrow", angle=45, line=dict(width=2, color="DarkSlateGrey") + ), + selector=dict(mode="markers"), +) +fig.show() + +``` + +### Setting Angle Reference + +*New in 5.11* + +In the previous example the angle reference is the default `up`, which +means all makers start at the angle reference point of 0. Set `angleref` to `previous` and a marker will take its angle reference from the previous data point. + +```python +import pandas as pd +import plotly.express as px +import plotly.graph_objects as go + +df = px.data.gapminder() + +fig = go.Figure() + +for x in df.loc[df.continent.isin(["Europe"])].country.unique()[:5]: + fil = df.loc[(df.country.str.contains(x))] + fig.add_trace( + go.Scatter( + x=fil["year"], + y=fil["pop"], + mode="lines+markers", + marker=dict( + symbol="arrow", + size=15, + angleref="previous", + ), + name=x, + ) + ) +fig.show() + +``` + +### Using Standoff to Position a Marker + +*New in 5.11* + +When you have multiple markers at one location, you can use `standoff` on a marker to move it away from the other marker in the direction of the `angle`. +In this example, we set `standoff=8` on the `arrow` marker, which is half the size of the other `circle` marker, meaning it points exactly at the `circle`. + +```python +import pandas as pd +import plotly.graph_objects as go +from plotly import data + +df = data.gapminder() +df = df.loc[(df.continent == "Americas") & (df.year.isin([1987, 2007]))] + +countries = ( + df.loc[(df.continent == "Americas") & (df.year.isin([2007]))] + .sort_values(by=["pop"], ascending=True)["country"] + .unique() +)[5:-10] + +data = {"x": [], "y": [], "colors": [], "years": []} + +for country in countries: + data["x"].extend( + [ + df.loc[(df.year == 1987) & (df.country == country)]["pop"].values[0], + df.loc[(df.year == 2007) & (df.country == country)]["pop"].values[0], + None, + ] + ) + data["y"].extend([country, country, None]), + data["colors"].extend(["cyan", "darkblue", "white"]), + data["years"].extend(["1987", "2007", None]) + +fig = go.Figure( + data=[ + go.Scatter( + x=data["x"], + y=data["y"], + mode="markers+lines", + marker=dict( + symbol="arrow", + color="royalblue", + size=16, + angleref="previous", + standoff=8, + ), + ), + go.Scatter( + x=data["x"], + y=data["y"], + text=data["years"], + mode="markers", + marker=dict( + color=data["colors"], + size=16, + ), + hovertemplate="""Country: %{y}
Population: %{x}
Year: %{text}
""", + ), + ] +) + +fig.update_layout( + title="Population changes 1987 to 2007", + width=1000, + height=1000, + showlegend=False, +) + + +fig.show() + +``` + ### Reference See https://plotly.com/python/reference/ for more information and chart attribute options! diff --git a/doc/python/scattermapbox.md b/doc/python/scattermapbox.md index 57e95452a69..05ff49c7b45 100644 --- a/doc/python/scattermapbox.md +++ b/doc/python/scattermapbox.md @@ -5,10 +5,10 @@ jupyter: text_representation: extension: .md format_name: markdown - format_version: '1.2' - jupytext_version: 1.4.2 + format_version: '1.3' + jupytext_version: 1.14.1 kernelspec: - display_name: Python 3 + display_name: Python 3 (ipykernel) language: python name: python3 language_info: @@ -20,7 +20,7 @@ jupyter: name: python nbconvert_exporter: python pygments_lexer: ipython3 - version: 3.7.7 + version: 3.8.0 plotly: description: How to make scatter plots on Mapbox maps in Python. display_as: maps @@ -245,7 +245,26 @@ fig.update_layout( fig.show() ``` +#### Add Clusters + +*New in 5.11* + +Display clusters of data points by setting `cluster`. Here, we enable clusters with `enabled=True`. You can also enable clusters by setting other `cluster` properties. Other available properties include `color` (for setting the color of the clusters), `size` (for setting the size of a cluster step), and `step` (for configuring how many points it takes to create a cluster or advance to the next cluster step. + +```python +import plotly.express as px +import pandas as pd + +px.set_mapbox_access_token(open(".mapbox_token").read()) +df = pd.read_csv( + "https://raw.githubusercontent.com/plotly/datasets/master/2011_february_us_airport_traffic.csv" +) +fig = px.scatter_mapbox(df, lat="lat", lon="long", size="cnt", zoom=3) +fig.update_traces(cluster=dict(enabled=True)) +fig.show() + +``` + #### Reference See [function reference for `px.(scatter_mapbox)`](https://plotly.com/python-api-reference/generated/plotly.express.scatter_mapbox) or https://plotly.com/python/reference/scattermapbox/ for more information and options! - diff --git a/doc/python/setting-graph-size.md b/doc/python/setting-graph-size.md index 65a632dd37a..611e0e29825 100644 --- a/doc/python/setting-graph-size.md +++ b/doc/python/setting-graph-size.md @@ -20,7 +20,7 @@ jupyter: name: python nbconvert_exporter: python pygments_lexer: ipython3 - version: 3.8.8 + version: 3.8.0 plotly: description: How to manipulate the graph size, margins and background color. display_as: file_settings @@ -163,6 +163,42 @@ fig.update_layout( fig.update_yaxes(automargin='left+top') +fig.show() +``` + +### Setting a Minimum Plot Size with Automargins + +*New in 5.11* + +To set a minimum width and height for a plot to be after automargin is applied, use `minreducedwidth` and `minreducedheight`. Here we set both to `250`. + +```python +import plotly.graph_objects as go + + +fig = go.Figure() + +fig.add_trace(go.Bar( + x=["Apples", "Oranges", "Watermelon", "Pears"], + y=[3, 2, 1, 4] +)) + +fig.update_layout( + autosize=False, + minreducedwidth=250, + minreducedheight=250, + width=450, + height=450, + yaxis=dict( + title_text="Y-axis Title", + ticktext=["Label", "Very long label", "Other label", "Very very long label"], + tickvals=[1, 2, 3, 4], + tickmode="array", + titlefont=dict(size=30), + ) +) + + fig.show() ```