📣 Dash 2.7 Released - Directional Arrows Feature, Map Bounds, and DataTable Filter Text

Update : version 2.9.2 has been released since this was posted.

We’re excited to announce that Dash 2.7.0 has been released :rocket:

pip install dash==2.7.0

Official Changelog :arrow_forward: Dash v2.7.0

Highlights :arrow_down_small:

Update Placeholder Text of DataTable Filter

  • As of Dash 2.7.0 you can update the placeholder text that belongs to the each column filter. To override the default filter field text, just assign the new text to the placeholder_text dictionary key belonging to the filter_options property of the DataTable.
filter_options={"placeholder_text": "Filter column..."}

Complete code example to produce the DataTable below:

from dash import Dash, dash_table
import pandas as pd

df = pd.read_csv(
    "https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv"
)[["country", "pop", "continent", "lifeExp"]]

app = Dash(__name__)

app.layout = dash_table.DataTable(
    df.to_dict("records"),
    [{"name": i, "id": i} for i in df.columns],
    filter_action="native",
    filter_options={"placeholder_text": "Filter column..."},
    page_size=10,
)

if __name__ == "__main__":
    app.run_server(debug=True)

Thank you @fraghag for creating the pull request that kickstarted this feature.

dcc.Graph Updates

Updated Plotly.js to from version 2.14.0 to version 2.16.1.

The version of Plotly.js that is built in here is the same one that is bundled with the recently released Plotly.py 5.11.0, so we recommend that you upgrade to Plotly 5.11.0 to get the full benefit of all of these libraries working together.

pip install plotly==5.11.0

Official Changelog :arrow_forward: Plotly v5.11.0

Setting Map Bounds

With Plotly 5.11.0 you can set the bounds of a map to specify an area outside of 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.

fig.update_layout(mapbox_bounds={"west": -180, "east": -50, "south": 20, "north": 90})

Complete code example to produce the map below:

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()

If you try to zoom out or move to different parts of the world, you’ll see that you cannot move south beyond Mexico City nor could you see Europe or Asia.

Dumbbell Charts with Arrow Heads

Arrow heads enable you to make functional dumbbell charts that indicate which direction the change occured with the arrowhead. More about the dumbbell with arrows in the docs.

import pandas as pd
import plotly.graph_objects as go
from plotly import data

df = data.gapminder()
df = df.loc[df.year.isin([1997, 2002])]
df = df.loc[df.country.isin (['Cuba','Argentina','Mexico','Venezuela','Costa Rica','Ecuador'])]

countries = (
    df.loc[(df.continent == "Americas") & (df.year.isin([2002]))]
    .sort_values(by=["gdpPercap"], ascending=True)["country"]
    .unique()
)

data = {"x": [], "y": [], "colors": [], "years": []}

for country in countries:
    data["x"].extend(
        [
            df.loc[(df.year == 1997) & (df.country == country)]["gdpPercap"].values[0],
            df.loc[(df.year == 2002) & (df.country == country)]["gdpPercap"].values[0],
            None,
        ]
    )
    data["y"].extend([country, country, None]),
    data["colors"].extend(["cyan", "darkblue", "white"]),
    data["years"].extend(["1997", "2002", 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} <br> GdpPercap: %{x} <br> Year: %{text} <br><extra></extra>""",
        ),
    ]
)

fig.update_layout(
    title="GDP per Capita changes 1997 to 2002",
    width=1000,
    height=1000,
    showlegend=False,
)


fig.show()

Arrows Along Lines

These arrows can also follow the direction of a line which results in a nice visual affect. More about the arrows in the docs.

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()

Parametric plots

Arrow heads are also great for indicating the direction that parametric plots trace.

import plotly.express as px

fig = px.line(x=[1,2,3,4,5,6,5,4,3,2,1], y=[4,7,9,11,13,15,17,20,22,24,27])

fig.update_traces(
    marker=dict(
        size=20, symbol="arrow", angleref="previous"
    ), mode="lines+markers"
)
fig.show()

Setting Marker Angles

You can change the angle of markers by setting angle . Here we set the angle on the arrow markers to 45 . More about setting marker angles in the docs.

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()

Notable Bug Fixes & Minor Changes

  • #2292 Pages: find the 404 page even if pages_folder is nested, or the 404 page is nested inside pages_folder. Thanks to @Divyessh for the contribution.
  • #2265 Removed deprecated before_first_request as reported in #2177. Thanks to @AnnMarieW for the contribution.
  • #2257 Fix tuple types in the TypeScript component generator. Thanks to @snehilvj for creating the issue.
  • #2293 Fix Dropdown useMemo not detecting equal objects. Thanks to @mariusdkm for the pull request.
  • #2277 Use dropdown styles from node_modules, instead of from stored css file. Thanks to @olejorgenb for opening the issue.
  • #2105 Fix order of dash component libraries imports. Thanks to @pikhovkin for the pull request.
  • #2291 Move flask-compress dependency to new extras requires dash[compress]
  • #2237 Ensure calls to plotly.js from dcc.Graph are properly sequenced even if React initiates multiple render cycles in quick succession.
  • #2218 Fix bug #1348 Validate children prop (required or not). Thanks to @siner308 and @alstn2468 for the pull request.
  • #2223 Exclude hidden folders when building dash.page_registry. Thanks to @AnnMarieW for the contribution.
  • #2182 Fix #2172 Make it so that when using pages, if suppress_callback_exceptions=True the validation_layout is not set. Thanks to @AnnMarieW for the pull request.
  • #2152 Fix bug #2128 preventing rendering of multiple components inside a dictionary.
  • #2187 Fix confusing error message when trying to use pytest fixtures but dash[testing] is not installed. Thanks to @martinschorb for reporting the bug.
  • #2202 Fix bug #2185 when you copy text with multiple quotes into a table. Thanks to @amy-morrill for the pull request.
  • #2226 Fix #2219 pages register & background callbacks.

Updates in Plotly 5.11.0:

  • Add clustering options to scattermapbox [#5827], with thanks to @elben10 for the contribution!
  • Add support for sankey links with arrows [#6276], with thanks to @Andy2003 for the contribution!
  • Add editSelection option to config [#6285]
  • Add bounds to mapbox suplots [6339]
  • Add angle, angleref and standoff to marker and add backoff to line; also introduce new arrow symbols to facilitate drawing networks [#6297]
  • Add minreducedwidth and minreducedheight to layout for increasing control over automargin [#6307]
  • Add entrywidth and entrywidthmode to legend [#6202, #6324]

Important Note

  • We dropped support for Internet Explorer. Our build process now targets vendor-supported browsers released in the last 7 years. This means support is available going back to ES2015, but over time this will naturally advance as older browser versions pass the 7-year threshold.

Previous Releases

:mega: Dash 2.6 Released - Background Callbacks, Unit Testing, Persistent Selections, Dropdown Features
:mega: Dash 2.5 Released - Easier Multi-Page Apps, Component Properties
:mega: Dash 2.4 Released - Improved Callback Context, Clientside Callback Promises, Typescript Components, Minor Ticks
:mega: Dash 2.3.0 Release - MathJax and fillpattern option in scatter trace
:mega: Dash 2.2.0 Release - Adds ticklabelstep to axes, and added dash.get_asset_url
:mega: Dash 2.1.0 Release - Autogenerated IDs and reärranged keyword arguments in Dash components

8 Likes