From f680f801dfa8dc4e2ebbdd194eded30b0a9c4993 Mon Sep 17 00:00:00 2001 From: Nicolas Kruchten Date: Mon, 2 Aug 2021 22:37:50 -0400 Subject: [PATCH 1/5] ability to show markers on lines --- .../plotly/plotly/express/_chart_types.py | 38 +++++++++++++++++-- .../python/plotly/plotly/express/_core.py | 9 ++++- packages/python/plotly/plotly/express/_doc.py | 4 ++ 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/packages/python/plotly/plotly/express/_chart_types.py b/packages/python/plotly/plotly/express/_chart_types.py index 50359ec0f66..0f7c34de66d 100644 --- a/packages/python/plotly/plotly/express/_chart_types.py +++ b/packages/python/plotly/plotly/express/_chart_types.py @@ -200,7 +200,9 @@ def density_heatmap( z=[ "For `density_heatmap` and `density_contour` these values are used as the inputs to `histfunc`.", ], - histfunc=["The arguments to this function are the values of `z`.",], + histfunc=[ + "The arguments to this function are the values of `z`.", + ], ), ) @@ -212,6 +214,7 @@ def line( line_group=None, color=None, line_dash=None, + symbol=None, hover_name=None, hover_data=None, custom_data=None, @@ -234,6 +237,9 @@ def line( color_discrete_map=None, line_dash_sequence=None, line_dash_map=None, + symbol_sequence=None, + symbol_map=None, + markers=False, log_x=False, log_y=False, range_x=None, @@ -261,6 +267,7 @@ def area( y=None, line_group=None, color=None, + symbol=None, hover_name=None, hover_data=None, custom_data=None, @@ -276,6 +283,9 @@ def area( labels=None, color_discrete_sequence=None, color_discrete_map=None, + symbol_sequence=None, + symbol_map=None, + markers=False, orientation=None, groupnorm=None, log_x=False, @@ -457,7 +467,9 @@ def histogram( args=locals(), constructor=go.Histogram, trace_patch=dict( - histnorm=histnorm, histfunc=histfunc, cumulative=dict(enabled=cumulative), + histnorm=histnorm, + histfunc=histfunc, + cumulative=dict(enabled=cumulative), ), layout_patch=dict(barmode=barmode, barnorm=barnorm), ) @@ -517,7 +529,11 @@ def violin( args=locals(), constructor=go.Violin, trace_patch=dict( - points=points, box=dict(visible=box), scalegroup=True, x0=" ", y0=" ", + points=points, + box=dict(visible=box), + scalegroup=True, + x0=" ", + y0=" ", ), layout_patch=dict(violinmode=violinmode), ) @@ -692,6 +708,7 @@ def line_3d( line_dash=None, text=None, line_group=None, + symbol=None, hover_name=None, hover_data=None, custom_data=None, @@ -709,6 +726,9 @@ def line_3d( color_discrete_map=None, line_dash_sequence=None, line_dash_map=None, + symbol_sequence=None, + symbol_map=None, + markers=False, log_x=False, log_y=False, log_z=False, @@ -778,6 +798,7 @@ def line_ternary( color=None, line_dash=None, line_group=None, + symbol=None, hover_name=None, hover_data=None, custom_data=None, @@ -790,6 +811,9 @@ def line_ternary( color_discrete_map=None, line_dash_sequence=None, line_dash_map=None, + symbol_sequence=None, + symbol_map=None, + markers=False, line_shape=None, title=None, template=None, @@ -862,6 +886,7 @@ def line_polar( custom_data=None, line_group=None, text=None, + symbol=None, animation_frame=None, animation_group=None, category_orders=None, @@ -870,6 +895,9 @@ def line_polar( color_discrete_map=None, line_dash_sequence=None, line_dash_map=None, + symbol_sequence=None, + symbol_map=None, + markers=False, direction="clockwise", start_angle=90, line_close=False, @@ -1067,6 +1095,7 @@ def line_geo( hover_data=None, custom_data=None, line_group=None, + symbol=None, animation_frame=None, animation_group=None, category_orders=None, @@ -1075,6 +1104,9 @@ def line_geo( color_discrete_map=None, line_dash_sequence=None, line_dash_map=None, + symbol_sequence=None, + symbol_map=None, + markers=False, projection=None, scope=None, center=None, diff --git a/packages/python/plotly/plotly/express/_core.py b/packages/python/plotly/plotly/express/_core.py index 4f1947ef9a4..f8e391053b9 100644 --- a/packages/python/plotly/plotly/express/_core.py +++ b/packages/python/plotly/plotly/express/_core.py @@ -1782,8 +1782,13 @@ def infer_config(args, constructor, trace_patch, layout_patch): trace_patch["opacity"] = args["opacity"] else: trace_patch["marker"] = dict(opacity=args["opacity"]) - if "line_group" in args: - trace_patch["mode"] = "lines" + ("+markers+text" if args["text"] else "") + if "line_group" in args: # px.line, px.line_*, px.area + modes = set(["lines"]) + if args.get("text") or args.get("symbol") or args.get("markers"): + modes.add("markers") + if args.get("text"): + modes.add("text") + trace_patch["mode"] = "+".join(modes) elif constructor != go.Splom and ( "symbol" in args or constructor == go.Scattermapbox ): diff --git a/packages/python/plotly/plotly/express/_doc.py b/packages/python/plotly/plotly/express/_doc.py index 62e709dc309..6fbbacd7d28 100644 --- a/packages/python/plotly/plotly/express/_doc.py +++ b/packages/python/plotly/plotly/express/_doc.py @@ -325,6 +325,10 @@ "Setting this value is recommended when using `plotly.express.colors.diverging` color scales as the inputs to `color_continuous_scale`.", ], size_max=["int (default `20`)", "Set the maximum mark size when using `size`."], + markers=[ + "boolean (default `False`)", + "If `True`, markers are shown on lines.", + ], log_x=[ "boolean (default `False`)", "If `True`, the x-axis is log-scaled in cartesian coordinates.", From f2dbe5a1aaf7bd8c0d88e488a6f846f224787757 Mon Sep 17 00:00:00 2001 From: Nicolas Kruchten Date: Mon, 2 Aug 2021 22:56:27 -0400 Subject: [PATCH 2/5] black --- .../python/plotly/plotly/express/_chart_types.py | 14 +++----------- packages/python/plotly/plotly/express/_doc.py | 5 +---- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/packages/python/plotly/plotly/express/_chart_types.py b/packages/python/plotly/plotly/express/_chart_types.py index 0f7c34de66d..6cfb6a90367 100644 --- a/packages/python/plotly/plotly/express/_chart_types.py +++ b/packages/python/plotly/plotly/express/_chart_types.py @@ -200,9 +200,7 @@ def density_heatmap( z=[ "For `density_heatmap` and `density_contour` these values are used as the inputs to `histfunc`.", ], - histfunc=[ - "The arguments to this function are the values of `z`.", - ], + histfunc=["The arguments to this function are the values of `z`.",], ), ) @@ -467,9 +465,7 @@ def histogram( args=locals(), constructor=go.Histogram, trace_patch=dict( - histnorm=histnorm, - histfunc=histfunc, - cumulative=dict(enabled=cumulative), + histnorm=histnorm, histfunc=histfunc, cumulative=dict(enabled=cumulative), ), layout_patch=dict(barmode=barmode, barnorm=barnorm), ) @@ -529,11 +525,7 @@ def violin( args=locals(), constructor=go.Violin, trace_patch=dict( - points=points, - box=dict(visible=box), - scalegroup=True, - x0=" ", - y0=" ", + points=points, box=dict(visible=box), scalegroup=True, x0=" ", y0=" ", ), layout_patch=dict(violinmode=violinmode), ) diff --git a/packages/python/plotly/plotly/express/_doc.py b/packages/python/plotly/plotly/express/_doc.py index 6fbbacd7d28..f2f2ab0544d 100644 --- a/packages/python/plotly/plotly/express/_doc.py +++ b/packages/python/plotly/plotly/express/_doc.py @@ -325,10 +325,7 @@ "Setting this value is recommended when using `plotly.express.colors.diverging` color scales as the inputs to `color_continuous_scale`.", ], size_max=["int (default `20`)", "Set the maximum mark size when using `size`."], - markers=[ - "boolean (default `False`)", - "If `True`, markers are shown on lines.", - ], + markers=["boolean (default `False`)", "If `True`, markers are shown on lines.",], log_x=[ "boolean (default `False`)", "If `True`, the x-axis is log-scaled in cartesian coordinates.", From 80509d5be22983b3838a2f8fabf7bb1395125db9 Mon Sep 17 00:00:00 2001 From: Nicolas Kruchten Date: Tue, 3 Aug 2021 14:45:14 -0400 Subject: [PATCH 3/5] improve scatter and line docs --- CHANGELOG.md | 1 + doc/python/axes.md | 2 +- doc/python/bubble-charts.md | 10 ++--- doc/python/categorical-axes.md | 35 ++++++++++++++++- doc/python/dot-plots.md | 17 +++++++-- doc/python/line-and-scatter.md | 70 ++++++++++++++++++++++++++++++---- doc/python/log-plot.md | 3 +- 7 files changed, 119 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62f9af32f61..8985395f77b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added - Extra flags were added to the `gapminder` and `stocks` dataset to facilitate testing, documentation and demos [#3305](https://github.com/plotly/plotly.py/issues/3305) + - All line-like Plotly Express functions now accept `markers` argument to display markers, and all but `line_mapbox` accept `symbol` to map a field to the symbol attribute, similar to scatter-like functions [#3326](https://github.com/plotly/plotly.py/issues/3326) ### Fixed - Fixed regression introduced in version 5.0.0 where pandas/numpy arrays with `dtype` of Object were being converted to `list` values when added to a Figure ([#3292](https://github.com/plotly/plotly.py/issues/3292), [#3293](https://github.com/plotly/plotly.py/pull/3293)) diff --git a/doc/python/axes.md b/doc/python/axes.md index 25186e0d62c..86c7d8ed4e2 100644 --- a/doc/python/axes.md +++ b/doc/python/axes.md @@ -51,7 +51,7 @@ Other kinds of subplots and axes are described in other tutorials: The different types of Cartesian axes are configured via the `xaxis.type` or `yaxis.type` attribute, which can take on the following values: - `'linear'` as described in this page -- `'log'` (see the [log plot tutorial](/python/log-plots/)) +- `'log'` (see the [log plot tutorial](/python/log-plot/)) - `'date'` (see the [tutorial on timeseries](/python/time-series/)) - `'category'` (see the [categorical axes tutorial](/python/categorical-axes/)) - `'multicategory'` (see the [categorical axes tutorial](/python/categorical-axes/)) diff --git a/doc/python/bubble-charts.md b/doc/python/bubble-charts.md index 411b6f0b990..b5bc5ad966d 100644 --- a/doc/python/bubble-charts.md +++ b/doc/python/bubble-charts.md @@ -5,8 +5,8 @@ jupyter: text_representation: extension: .md format_name: markdown - format_version: '1.1' - jupytext_version: 1.1.1 + format_version: '1.2' + jupytext_version: 1.4.2 kernelspec: display_name: Python 3 language: python @@ -20,7 +20,7 @@ jupyter: name: python nbconvert_exporter: python pygments_lexer: ipython3 - version: 3.6.7 + version: 3.7.7 plotly: description: How to make bubble charts in Python with Plotly. display_as: basic @@ -36,7 +36,7 @@ jupyter: ## Bubble chart with plotly.express -A [bubble chart](https://en.wikipedia.org/wiki/Bubble_chart) is a scatter plot in which a third dimension of the data is shown through the size of markers. For other types of scatter plot, see the [line and scatter page](https://plotly.com/python/line-and-scatter/). +A [bubble chart](https://en.wikipedia.org/wiki/Bubble_chart) is a scatter plot in which a third dimension of the data is shown through the size of markers. For other types of scatter plot, see the [scatter plot documentation](https://plotly.com/python/line-and-scatter/). We first show a bubble chart example using Plotly Express. [Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). The size of markers is set from the dataframe column given as the `size` parameter. @@ -222,4 +222,4 @@ fig.show() ### Reference -See https://plotly.com/python/reference/scatter/ for more information and chart attribute options! \ No newline at end of file +See https://plotly.com/python/reference/scatter/ for more information and chart attribute options! diff --git a/doc/python/categorical-axes.md b/doc/python/categorical-axes.md index 0f1bdc7a86f..ec59627904e 100644 --- a/doc/python/categorical-axes.md +++ b/doc/python/categorical-axes.md @@ -41,7 +41,7 @@ This page shows examples of how to configure [2-dimensional Cartesian axes](/pyt The different types of Cartesian axes are configured via the `xaxis.type` or `yaxis.type` attribute, which can take on the following values: - `'linear'` (see the [linear axes tutorial](/python/axes/)) -- `'log'` (see the [log plot tutorial](/python/log-plots/)) +- `'log'` (see the [log plot tutorial](/python/log-plot/)) - `'date'` (see the [tutorial on timeseries](/python/time-series/)) - `'category'` see below - `'multicategory'` see below @@ -64,6 +64,39 @@ fig.update_xaxes(type='category') fig.show() ``` +### Categorical Axes and Trace Types + +Every cartesian trace type is compatible with categorical axes, not just `bar`. + +Scatter plots where one axis is categorical are often known as [dot plots](https://plotly.com/python/dot-plots/). + +```python +import plotly.express as px +df = px.data.medals_long() + +fig = px.scatter(df, y="nation", x="count", color="medal", symbol="medal") +fig.update_traces(marker_size=10) +fig.show() +``` + +[Box plots]() and [violin plots]() are often shown with one categorical and one continuous axis. + +```python +import plotly.express as px +df = px.data.tips() + +fig = px.box(df, x="sex", y="total_bill", color="smoker") +fig.show() +``` + +```python +import plotly.express as px +df = px.data.tips() + +fig = px.violin(df, x="sex", y="total_bill", color="smoker") +fig.show() +``` + ### Controlling the Category Order with Plotly Express [Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). diff --git a/doc/python/dot-plots.md b/doc/python/dot-plots.md index 576f82dd391..ed9d7b6c239 100644 --- a/doc/python/dot-plots.md +++ b/doc/python/dot-plots.md @@ -5,8 +5,8 @@ jupyter: text_representation: extension: .md format_name: markdown - format_version: '1.1' - jupytext_version: 1.1.1 + format_version: '1.2' + jupytext_version: 1.4.2 kernelspec: display_name: Python 3 language: python @@ -20,7 +20,7 @@ jupyter: name: python nbconvert_exporter: python pygments_lexer: ipython3 - version: 3.6.7 + version: 3.7.7 plotly: description: How to make dot plots in Python with Plotly. display_as: basic @@ -35,12 +35,21 @@ jupyter: #### Basic Dot Plot -Dot plots (also known as [Cleveland dot plots]()) show changes between two (or more) points in time or between two (or more) conditions. Compared to a [bar chart](/python/bar-charts/), dot plots can be less cluttered and allow for an easier comparison between conditions. +Dot plots (also known as [Cleveland dot plots]()) are [scatter plots](https://plotly.com/python/line-and-scatter/) with one categorical axis and one continuous axis. They can be used to show changes between two (or more) points in time or between two (or more) conditions. Compared to a [bar chart](/python/bar-charts/), dot plots can be less cluttered and allow for an easier comparison between conditions. For the same data, we show below how to create a dot plot using either `px.scatter` or `go.Scatter`. [Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +```python +import plotly.express as px +df = px.data.medals_long() + +fig = px.scatter(df, y="nation", x="count", color="medal", symbol="medal") +fig.update_traces(marker_size=10) +fig.show() +``` + ```python import plotly.express as px import pandas as pd diff --git a/doc/python/line-and-scatter.md b/doc/python/line-and-scatter.md index b2dea35439b..e6680d9b5c0 100644 --- a/doc/python/line-and-scatter.md +++ b/doc/python/line-and-scatter.md @@ -6,7 +6,7 @@ jupyter: extension: .md format_name: markdown format_version: '1.2' - jupytext_version: 1.6.0 + jupytext_version: 1.4.2 kernelspec: display_name: Python 3 language: python @@ -34,7 +34,7 @@ jupyter: thumbnail: thumbnail/line-and-scatter.jpg --- -## Scatter plot with Plotly Express +## Scatter plots with Plotly Express [Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). @@ -55,9 +55,9 @@ fig = px.scatter(df, x="sepal_width", y="sepal_length") fig.show() ``` -#### Set size and color with column names +#### Setting size and color with column names -Note that `color` and `size` data are added to hover information. You can add other columns to hover data with the `hover_data` argument of `px.scatter`. +Scatter plots with variable-sized circular markers are often known as [bubble charts](https://plotly.com/python/bubble-charts/). Note that `color` and `size` data are added to hover information. You can add other columns to hover data with the `hover_data` argument of `px.scatter`. ```python import plotly.express as px @@ -67,7 +67,16 @@ fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species", fig.show() ``` -## Scatter plot in Dash +The `symbol` argument can be mapped to a column as well. A [wide variety of symbols](https://plotly.com/python/marker-style/) are available. + +```python +import plotly.express as px +df = px.data.iris() +fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species", symbol="species") +fig.show() +``` + +## Scatter plots in Dash [Dash](https://plotly.com/dash/) is the best way to build analytical apps in Python using Plotly figures. To run the app below, run `pip install dash`, click "Download" to get the code and run `python app.py`. @@ -80,7 +89,22 @@ snippet_url = 'https://dash-gallery.plotly.host/python-docs-dash-snippets/' IFrame(snippet_url + 'line-and-scatter', width='100%', height=630) ``` -## Line plot with Plotly Express +### Scatter plots and Categorical Axes + +Scatters plots can be made on using any type of cartesian axis, including [linear](https://plotly.com/python/axes/), [logarithmic](https://plotly.com/python/log-plot/), [categorical](https://plotly.com/python/categorical-axes/) or [date](https://plotly.com/python/time-series/) axes. + +Scatter plots where one axis is categorical are often known as [dot plots](https://plotly.com/python/dot-plots/). + +```python +import plotly.express as px +df = px.data.medals_long() + +fig = px.scatter(df, y="nation", x="count", color="medal", symbol="medal") +fig.update_traces(marker_size=10) +fig.show() +``` + +## Line plots with Plotly Express ```python import plotly.express as px @@ -99,7 +123,39 @@ fig = px.line(df, x='year', y='lifeExp', color='country') fig.show() ``` -## Scatter and line plot with go.Scatter +The `markers` argument can be set to `True` to show markers on lines. + +```python +import plotly.express as px +df = px.data.gapminder().query("continent == 'Oceania'") +fig = px.line(df, x='year', y='lifeExp', color='country', markers=True) +fig.show() +``` + +The `symbol` argument can be used to map a data field to the marker symbol. A [wide variety of symbols](https://plotly.com/python/marker-style/) are available. + +```python +import plotly.express as px +df = px.data.gapminder().query("continent == 'Oceania'") +fig = px.line(df, x='year', y='lifeExp', color='country', symbol="country") +fig.show() +``` + +### Line plots on Date axes + +Line plots can be made on using any type of cartesian axis, including [linear](https://plotly.com/python/axes/), [logarithmic](https://plotly.com/python/log-plot/), [categorical](https://plotly.com/python/categorical-axes/) or date axes. Line plots on date axes are often called [time-series charts](https://plotly.com/python/time-series/). + +Plotly auto-sets the axis type to a date format when the corresponding data are either ISO-formatted date strings or if they're a [date pandas column](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html) or [datetime NumPy array](https://docs.scipy.org/doc/numpy/reference/arrays.datetime.html). + +```python +import plotly.express as px + +df = px.data.stocks() +fig = px.line(df, x='date', y="GOOG") +fig.show() +``` + +## Scatter and line plots with go.Scatter If Plotly Express does not provide a good starting point, it is possible to use [the more generic `go.Scatter` class from `plotly.graph_objects`](/python/graph-objects/). Whereas `plotly.express` has two functions `scatter` and `line`, `go.Scatter` can be used both for plotting points (makers) or lines, depending on the value of `mode`. The different options of `go.Scatter` are documented in its [reference page](https://plotly.com/python/reference/scatter/). diff --git a/doc/python/log-plot.md b/doc/python/log-plot.md index 2c78453c752..7cd2d64932e 100644 --- a/doc/python/log-plot.md +++ b/doc/python/log-plot.md @@ -29,6 +29,7 @@ jupyter: name: Log Plots order: 5 permalink: python/log-plot/ + redirect_from: python/log-plots/ thumbnail: thumbnail/log.jpg --- @@ -54,7 +55,7 @@ Setting the range of a logarithmic axis with Plotly Express works the same was a import plotly.express as px df = px.data.gapminder().query("year == 2007") -fig = px.scatter(df, x="gdpPercap", y="lifeExp", hover_name="country", +fig = px.scatter(df, x="gdpPercap", y="lifeExp", hover_name="country", log_x=True, range_x=[1,100000], range_y=[0,100]) fig.show() ``` From 1cafc5f8a2a1adb3d3a2c8cfff987d9f46887b12 Mon Sep 17 00:00:00 2001 From: Nicolas Kruchten Date: Tue, 3 Aug 2021 14:47:52 -0400 Subject: [PATCH 4/5] add all datasets to PX export for docs --- packages/python/plotly/plotly/express/data/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/python/plotly/plotly/express/data/__init__.py b/packages/python/plotly/plotly/express/data/__init__.py index f4bc598bcb8..58fc678f1c4 100644 --- a/packages/python/plotly/plotly/express/data/__init__.py +++ b/packages/python/plotly/plotly/express/data/__init__.py @@ -8,8 +8,12 @@ "carshare", "election", "election_geojson", + "experiment", "gapminder", "iris", + "medals_wide", + "medals_long", + "stocks", "tips", "wind", ] From 3befb2c334cb83798e501b48ea4c49ead89cfd87 Mon Sep 17 00:00:00 2001 From: Nicolas Kruchten Date: Tue, 3 Aug 2021 15:25:01 -0400 Subject: [PATCH 5/5] more line docs --- doc/python/line-and-scatter.md | 36 ++++++++++++++ doc/python/line-charts.md | 89 ++++++++++++++++++++++++++++------ 2 files changed, 110 insertions(+), 15 deletions(-) diff --git a/doc/python/line-and-scatter.md b/doc/python/line-and-scatter.md index e6680d9b5c0..b99afa56d5b 100644 --- a/doc/python/line-and-scatter.md +++ b/doc/python/line-and-scatter.md @@ -155,6 +155,42 @@ fig = px.line(df, x='date', y="GOOG") fig.show() ``` +### Data Order in Scatter and Line Charts + +Plotly line charts are implemented as [connected scatterplots](https://www.data-to-viz.com/graph/connectedscatter.html) (see below), meaning that the points are plotted and connected with lines **in the order they are provided, with no automatic reordering**. + +This makes it possible to make charts like the one below, but also means that it may be required to explicitly sort data before passing it to Plotly to avoid lines moving "backwards" across the chart. + +```python +import plotly.express as px +import pandas as pd + +df = pd.DataFrame(dict( + x = [1, 3, 2, 4], + y = [1, 2, 3, 4] +)) +fig = px.line(df, x="x", y="y", title="Unsorted Input") +fig.show() + +df = df.sort_values(by="x") +fig = px.line(df, x="x", y="y", title="Sorted Input") +fig.show() +``` + +### Connected Scatterplots + +In a connected scatterplot, two continuous variables are plotted against each other, with a line connecting them in some meaningful order, usually a time variable. In the plot below, we show the "trajectory" of a pair of countries through a space defined by GDP per Capita and Life Expectancy. Botswana's life expectancy + +```python +import plotly.express as px + +df = px.data.gapminder().query("country in ['Canada', 'Botswana']") + +fig = px.line(df, x="lifeExp", y="gdpPercap", color="country", text="year") +fig.update_traces(textposition="bottom right") +fig.show() +``` + ## Scatter and line plots with go.Scatter If Plotly Express does not provide a good starting point, it is possible to use [the more generic `go.Scatter` class from `plotly.graph_objects`](/python/graph-objects/). Whereas `plotly.express` has two functions `scatter` and `line`, `go.Scatter` can be used both for plotting points (makers) or lines, depending on the value of `mode`. The different options of `go.Scatter` are documented in its [reference page](https://plotly.com/python/reference/scatter/). diff --git a/doc/python/line-charts.md b/doc/python/line-charts.md index 5dbbbb94889..f2a0a3cd76c 100644 --- a/doc/python/line-charts.md +++ b/doc/python/line-charts.md @@ -6,7 +6,7 @@ jupyter: extension: .md format_name: markdown format_version: '1.2' - jupytext_version: 1.6.0 + jupytext_version: 1.4.2 kernelspec: display_name: Python 3 language: python @@ -34,14 +34,12 @@ jupyter: thumbnail: thumbnail/line-plot.jpg --- -### Line Plot with plotly.express +### Line Plots with plotly.express [Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). With `px.line`, each data point is represented as a vertex (which location is given by the `x` and `y` columns) of a **polyline mark** in 2D space. For more examples of line plots, see the [line and scatter notebook](https://plotly.com/python/line-and-scatter/). -#### Simple Line Plot with plotly.express - ```python import plotly.express as px @@ -50,7 +48,7 @@ fig = px.line(df, x="year", y="lifeExp", title='Life expectancy in Canada') fig.show() ``` -### Line Plot with column encoding color +### Line Plots with column encoding color ```python import plotly.express as px @@ -60,26 +58,87 @@ fig = px.line(df, x="year", y="lifeExp", color='country') fig.show() ``` +### Line charts in Dash + +[Dash](https://plotly.com/dash/) is the best way to build analytical apps in Python using Plotly figures. To run the app below, run `pip install dash`, click "Download" to get the code and run `python app.py`. + +Get started with [the official Dash docs](https://dash.plotly.com/installation) and **learn how to effortlessly [style](https://plotly.com/dash/design-kit/) & [deploy](https://plotly.com/dash/app-manager/) apps like this with Dash Enterprise.** + + +```python hide_code=true tags=[] +from IPython.display import IFrame +snippet_url = 'https://dash-gallery.plotly.host/python-docs-dash-snippets/' +IFrame(snippet_url + 'line-charts', width='100%', height=630) +``` + +### Data Order in Line Charts + +Plotly line charts are implemented as [connected scatterplots](https://www.data-to-viz.com/graph/connectedscatter.html) (see below), meaning that the points are plotted and connected with lines **in the order they are provided, with no automatic reordering**. + +This makes it possible to make charts like the one below, but also means that it may be required to explicitly sort data before passing it to Plotly to avoid lines moving "backwards" across the chart. + ```python import plotly.express as px +import pandas as pd + +df = pd.DataFrame(dict( + x = [1, 3, 2, 4], + y = [1, 2, 3, 4] +)) +fig = px.line(df, x="x", y="y", title="Unsorted Input") +fig.show() -df = px.data.gapminder().query("continent != 'Asia'") # remove Asia for visibility -fig = px.line(df, x="year", y="lifeExp", color="continent", - line_group="country", hover_name="country") +df = df.sort_values(by="x") +fig = px.line(df, x="x", y="y", title="Sorted Input") fig.show() ``` -### Line chart in Dash +### Connected Scatterplots -[Dash](https://plotly.com/dash/) is the best way to build analytical apps in Python using Plotly figures. To run the app below, run `pip install dash`, click "Download" to get the code and run `python app.py`. +In a connected scatterplot, two continuous variables are plotted against each other, with a line connecting them in some meaningful order, usually a time variable. In the plot below, we show the "trajectory" of a pair of countries through a space defined by GDP per Capita and Life Expectancy. Botswana's life expectancy -Get started with [the official Dash docs](https://dash.plotly.com/installation) and **learn how to effortlessly [style](https://plotly.com/dash/design-kit/) & [deploy](https://plotly.com/dash/app-manager/) apps like this with Dash Enterprise.** +```python +import plotly.express as px +df = px.data.gapminder().query("country in ['Canada', 'Botswana']") -```python hide_code=true -from IPython.display import IFrame -snippet_url = 'https://dash-gallery.plotly.host/python-docs-dash-snippets/' -IFrame(snippet_url + 'line-charts', width='100%', height=630) +fig = px.line(df, x="lifeExp", y="gdpPercap", color="country", text="year") +fig.update_traces(textposition="bottom right") +fig.show() +``` + +### Line charts with markers + +The `markers` argument can be set to `True` to show markers on lines. + +```python +import plotly.express as px +df = px.data.gapminder().query("continent == 'Oceania'") +fig = px.line(df, x='year', y='lifeExp', color='country', markers=True) +fig.show() +``` + +The `symbol` argument can be used to map a data field to the marker symbol. A [wide variety of symbols](https://plotly.com/python/marker-style/) are available. + +```python +import plotly.express as px +df = px.data.gapminder().query("continent == 'Oceania'") +fig = px.line(df, x='year', y='lifeExp', color='country', symbol="country") +fig.show() +``` + +### Line plots on Date axes + +Line plots can be made on using any type of cartesian axis, including [linear](https://plotly.com/python/axes/), [logarithmic](https://plotly.com/python/log-plot/), [categorical](https://plotly.com/python/categorical-axes/) or date axes. Line plots on date axes are often called [time-series charts](https://plotly.com/python/time-series/). + +Plotly auto-sets the axis type to a date format when the corresponding data are either ISO-formatted date strings or if they're a [date pandas column](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html) or [datetime NumPy array](https://docs.scipy.org/doc/numpy/reference/arrays.datetime.html). + +```python +import plotly.express as px + +df = px.data.stocks() +fig = px.line(df, x='date', y="GOOG") +fig.show() ``` ### Sparklines with Plotly Express