From 2ef18bbff75b0019f27f2fa59cee33917c272fb4 Mon Sep 17 00:00:00 2001 From: Nicolas Kruchten Date: Tue, 26 May 2020 08:27:14 -0400 Subject: [PATCH 1/8] Fix for pandas pattern --- packages/python/plotly/plotly/express/_core.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/python/plotly/plotly/express/_core.py b/packages/python/plotly/plotly/express/_core.py index 216b16716c9..0b4fddc3468 100644 --- a/packages/python/plotly/plotly/express/_core.py +++ b/packages/python/plotly/plotly/express/_core.py @@ -1069,11 +1069,8 @@ def process_args_into_dataframe(args, wide_mode, var_name, value_name): constants[col_name] = argument.value else: ranges.append(col_name) - # ----------------- argument is a col name ---------------------- - elif isinstance(argument, str) or isinstance( - argument, int - ): # just a column name given as str or int - + # ----------------- argument is likely a col name ---------------------- + elif isinstance(argument, str) or not hasattr(argument, "__len__"): if ( field_name == "hover_data" and hover_data_is_dict @@ -1135,7 +1132,7 @@ def process_args_into_dataframe(args, wide_mode, var_name, value_name): else: col_name = str(argument) df_output[col_name] = df_input[argument].values - # ----------------- argument is a column / array / list.... ------- + # ----------------- argument is likely a column / array / list.... ------- else: if df_provided and hasattr(argument, "name"): if argument is df_input.index: From f6627a352ab7d3fd3311120b40cd6309bf166a25 Mon Sep 17 00:00:00 2001 From: Nicolas Kruchten Date: Tue, 26 May 2020 08:30:53 -0400 Subject: [PATCH 2/8] doc tweaks --- doc/python/pandas-backend.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/python/pandas-backend.md b/doc/python/pandas-backend.md index 17eb84a7110..67bc4fc48ef 100644 --- a/doc/python/pandas-backend.md +++ b/doc/python/pandas-backend.md @@ -36,9 +36,9 @@ jupyter: ### Introduction -The popular [Pandas](https://pandas.pydata.org/) data analysis and manipulation tool provides plotting functions on its `DataFrame` and `Series` objects, which have historically produced `matplotlib` plots. Since version 0.25, Pandas has provided a mechanism to use different backends, and as of version 4.8 of `plotly`, you can now use a [Plotly Express-powered](/python/plotly-express/) backend for Pandas plotting. +The popular [Pandas](https://pandas.pydata.org/) data analysis and manipulation tool provides [plotting functions on its `DataFrame` and `Series` objects](https://pandas.pydata.org/pandas-docs/stable/user_guide/visualization.html), which have historically produced `matplotlib` plots. Since version 0.25, Pandas has provided a mechanism to use different backends, and as of version 4.8 of `plotly`, you can now use a [Plotly Express-powered](/python/plotly-express/) backend for Pandas plotting. This means you can now produce interactive plots directly from a data frame, without even needing to import Plotly. -To activate it, you just need to set `pd.options.plotting.backend` to `"plotly"` and call `.plot()` to get a `plotly.graph_objects.Figure` object back, just like if you had called Plotly Express directly: +To activate this backend, you will need to [have Plotly installed](/python/getting-started/), and then just need to set `pd.options.plotting.backend` to `"plotly"` and call `.plot()` to get a `plotly.graph_objects.Figure` object back, just like if you had called Plotly Express directly: ```python import pandas as pd @@ -64,9 +64,9 @@ fig.show() ### A Note on API Compatibility -> The Plotly plotting backend for Pandas is *not intended* to be a drop-in replacement for the default; it does not implement all or even most of the same keyword arguments, such as `subplots=True` etc. +> The Plotly plotting backend for Pandas is *not intended* to be a drop-in replacement for the default; it does not implement all or even most of the same keyword arguments, such as `subplots=True` etc. -The Plotly plotting backend for Pandas is a more convenient way to invoke certain [Plotly Express](/python/plotly-express/) functions by chaining a `.plot()` call without having to import Plotly Express directly. Plotly Express, as of version 4.8 with [wide-form data support](/python/wide-form/) implements behaviour for the `x` and `y` keywords that are very simlar to the `matplotlib` backend. +The Plotly plotting backend for Pandas is a more convenient way to invoke certain [Plotly Express](/python/plotly-express/) functions by chaining a `.plot()` call without having to import Plotly Express directly. Plotly Express, as of version 4.8 with [wide-form data support](/python/wide-form/) in addition to its robust long-form data support, implements behaviour for the `x` and `y` keywords that are very simlar to the `matplotlib` backend. In practice, this means that the following two ways of making a chart are identical and support the same additional arguments, because they call the same underlying code: @@ -85,7 +85,7 @@ fig2 = px.bar(df) fig2.show() ``` -To achieve a similar effect to `subplots=True`, the [Plotly Express `facet_row` and `facet_col` options](/python/facet-plots/) can be used, the same was as they work when directly calling [Plotly Express with wide-form data](/python/wide-form/): +To achieve a similar effect to `subplots=True`, for example, the [Plotly Express `facet_row` and `facet_col` options](/python/facet-plots/) can be used, the same was as they work when directly calling [Plotly Express with wide-form data](/python/wide-form/): ```python import pandas as pd @@ -98,7 +98,7 @@ fig.show() ### Supported Methods -The Plotly backend supports the following `kind`s of Pandas plots: `scatter`, `line`, `area`, `bar`, `barh`, `hist` and `box`, via the call pattern `df.plot(kind='scatter')` or `df.plot.scatter()`. +The Plotly backend supports the following `kind`s of Pandas plots: `scatter`, `line`, `area`, `bar`, `barh`, `hist` and `box`, via the call pattern `df.plot(kind='scatter')` or `df.plot.scatter()`. These delegate to the corresponding Plotly Express functions. ```python import pandas as pd @@ -107,7 +107,7 @@ pd.options.plotting.backend = "plotly" np.random.seed(1) df = pd.DataFrame(dict( - a=np.random.normal(loc=1, scale=2, size=100), + a=np.random.normal(loc=1, scale=2, size=100), b=np.random.normal(loc=2, scale=1, size=100) )) fig = df.plot.scatter(x="a", y="b") @@ -157,7 +157,7 @@ pd.options.plotting.backend = "plotly" np.random.seed(1) df = pd.DataFrame(dict( - a=np.random.normal(loc=1, scale=2, size=100), + a=np.random.normal(loc=1, scale=2, size=100), b=np.random.normal(loc=2, scale=1, size=100) )) fig = df.plot.hist() @@ -171,7 +171,7 @@ pd.options.plotting.backend = "plotly" np.random.seed(1) df = pd.DataFrame(dict( - a=np.random.normal(loc=1, scale=2, size=100), + a=np.random.normal(loc=1, scale=2, size=100), b=np.random.normal(loc=2, scale=1, size=100) )) fig = df.plot.box() @@ -189,7 +189,7 @@ pd.options.plotting.backend = "plotly" np.random.seed(1) df = pd.DataFrame(dict( - a=np.random.normal(loc=1, scale=2, size=100), + a=np.random.normal(loc=1, scale=2, size=100), b=np.random.normal(loc=2, scale=1, size=100) )) fig = df.boxplot() From 7b7006b85b9c18baf5725d8fa2da5bed189c79ee Mon Sep 17 00:00:00 2001 From: Nicolas Kruchten Date: Tue, 26 May 2020 08:34:19 -0400 Subject: [PATCH 3/8] add test --- .../plotly/tests/test_core/test_px/test_pandas_backend.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/python/plotly/plotly/tests/test_core/test_px/test_pandas_backend.py b/packages/python/plotly/plotly/tests/test_core/test_px/test_pandas_backend.py index 31213410147..6bd57a77563 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_px/test_pandas_backend.py +++ b/packages/python/plotly/plotly/tests/test_core/test_px/test_pandas_backend.py @@ -28,3 +28,11 @@ def test_pandas_equiv(pandas_fn, px_fn): pd.options.plotting.backend = "plotly" df = pd.DataFrame(np.random.randn(100, 4), columns=list("ABCD")).cumsum() assert pandas_fn(df) == px_fn(df) + + +def test_pandas_example(): + pd.options.plotting.backend = "plotly" + ts = pd.Series(np.random.randn(1000), index=pd.date_range("1/1/2000", periods=1000)) + df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index, columns=list("ABCD")) + fig = df.iloc[5].plot.bar() + assert len(fig.data) == 1 From 67852ade556a5c668e162e3eeecf22e7cf7e6e5b Mon Sep 17 00:00:00 2001 From: Nicolas Kruchten Date: Tue, 26 May 2020 08:39:09 -0400 Subject: [PATCH 4/8] fixing CI --- packages/python/plotly/optional-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/python/plotly/optional-requirements.txt b/packages/python/plotly/optional-requirements.txt index 9886dcd1872..04aee482190 100644 --- a/packages/python/plotly/optional-requirements.txt +++ b/packages/python/plotly/optional-requirements.txt @@ -36,7 +36,7 @@ colorcet ipython ## pandas deps for some matplotlib functionality ## -pandas +pandas==1.0.3 ## scipy deps for some FigureFactory functions ## scipy From c08c62116f57f4c58c947e1bb4278e20966f27e8 Mon Sep 17 00:00:00 2001 From: Nicolas Kruchten Date: Tue, 26 May 2020 08:44:35 -0400 Subject: [PATCH 5/8] fixing CI --- packages/python/plotly/tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/python/plotly/tox.ini b/packages/python/plotly/tox.ini index dddc6e69ec4..62f11791be5 100644 --- a/packages/python/plotly/tox.ini +++ b/packages/python/plotly/tox.ini @@ -57,7 +57,7 @@ deps= pytz==2016.10 retrying==1.3.3 pytest==3.5.1 - pandas==0.24.2 + pandas==1.0.3 xarray==0.10.9 statsmodels==0.10.2 backports.tempfile==1.0 From f36d5e085892546fc6763ceb10daf0e4bc617875 Mon Sep 17 00:00:00 2001 From: Nicolas Kruchten Date: Tue, 26 May 2020 08:49:29 -0400 Subject: [PATCH 6/8] fixing CI --- .circleci/create_conda_optional_env.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/create_conda_optional_env.sh b/.circleci/create_conda_optional_env.sh index 17f3c999af8..7a39e782602 100755 --- a/.circleci/create_conda_optional_env.sh +++ b/.circleci/create_conda_optional_env.sh @@ -16,7 +16,7 @@ if [ ! -d $HOME/miniconda/envs/circle_optional ]; then # Create environment # PYTHON_VERSION=2.7 or 3.5 $HOME/miniconda/bin/conda create -n circle_optional --yes python=$PYTHON_VERSION \ -requests nbformat six retrying psutil pandas decorator pytest mock nose poppler xarray scikit-image ipython jupyter ipykernel ipywidgets statsmodels +requests nbformat six retrying psutil pandas==1.0.3 decorator pytest mock nose poppler xarray scikit-image ipython jupyter ipykernel ipywidgets statsmodels # Install orca into environment $HOME/miniconda/bin/conda install --yes -n circle_optional -c plotly plotly-orca==1.3.1 From eb3f8c5f3a5097f655bca061affedab95b288120 Mon Sep 17 00:00:00 2001 From: Nicolas Kruchten Date: Tue, 26 May 2020 08:51:34 -0400 Subject: [PATCH 7/8] fixing CI --- .circleci/create_conda_optional_env.sh | 2 +- packages/python/plotly/optional-requirements.txt | 2 +- .../plotly/tests/test_core/test_px/test_pandas_backend.py | 4 ++++ packages/python/plotly/tox.ini | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.circleci/create_conda_optional_env.sh b/.circleci/create_conda_optional_env.sh index 7a39e782602..17f3c999af8 100755 --- a/.circleci/create_conda_optional_env.sh +++ b/.circleci/create_conda_optional_env.sh @@ -16,7 +16,7 @@ if [ ! -d $HOME/miniconda/envs/circle_optional ]; then # Create environment # PYTHON_VERSION=2.7 or 3.5 $HOME/miniconda/bin/conda create -n circle_optional --yes python=$PYTHON_VERSION \ -requests nbformat six retrying psutil pandas==1.0.3 decorator pytest mock nose poppler xarray scikit-image ipython jupyter ipykernel ipywidgets statsmodels +requests nbformat six retrying psutil pandas decorator pytest mock nose poppler xarray scikit-image ipython jupyter ipykernel ipywidgets statsmodels # Install orca into environment $HOME/miniconda/bin/conda install --yes -n circle_optional -c plotly plotly-orca==1.3.1 diff --git a/packages/python/plotly/optional-requirements.txt b/packages/python/plotly/optional-requirements.txt index 04aee482190..9886dcd1872 100644 --- a/packages/python/plotly/optional-requirements.txt +++ b/packages/python/plotly/optional-requirements.txt @@ -36,7 +36,7 @@ colorcet ipython ## pandas deps for some matplotlib functionality ## -pandas==1.0.3 +pandas ## scipy deps for some FigureFactory functions ## scipy diff --git a/packages/python/plotly/plotly/tests/test_core/test_px/test_pandas_backend.py b/packages/python/plotly/plotly/tests/test_core/test_px/test_pandas_backend.py index 6bd57a77563..87433de203e 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_px/test_pandas_backend.py +++ b/packages/python/plotly/plotly/tests/test_core/test_px/test_pandas_backend.py @@ -24,6 +24,10 @@ (lambda df: df["A"].hist(), lambda df: px.histogram(df["A"])), ], ) +@pytest.mark.skipif( + not hasattr(pd.options.plotting, "backend"), + reason="Currently installed pandas doesn't support plotting backends.", +) def test_pandas_equiv(pandas_fn, px_fn): pd.options.plotting.backend = "plotly" df = pd.DataFrame(np.random.randn(100, 4), columns=list("ABCD")).cumsum() diff --git a/packages/python/plotly/tox.ini b/packages/python/plotly/tox.ini index 62f11791be5..dddc6e69ec4 100644 --- a/packages/python/plotly/tox.ini +++ b/packages/python/plotly/tox.ini @@ -57,7 +57,7 @@ deps= pytz==2016.10 retrying==1.3.3 pytest==3.5.1 - pandas==1.0.3 + pandas==0.24.2 xarray==0.10.9 statsmodels==0.10.2 backports.tempfile==1.0 From 940c6792b3c8aa47980132a12a4d8388499023b0 Mon Sep 17 00:00:00 2001 From: Nicolas Kruchten Date: Tue, 26 May 2020 08:52:29 -0400 Subject: [PATCH 8/8] fixing CI --- .../plotly/tests/test_core/test_px/test_pandas_backend.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/python/plotly/plotly/tests/test_core/test_px/test_pandas_backend.py b/packages/python/plotly/plotly/tests/test_core/test_px/test_pandas_backend.py index 87433de203e..33df17d9043 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_px/test_pandas_backend.py +++ b/packages/python/plotly/plotly/tests/test_core/test_px/test_pandas_backend.py @@ -24,16 +24,16 @@ (lambda df: df["A"].hist(), lambda df: px.histogram(df["A"])), ], ) -@pytest.mark.skipif( - not hasattr(pd.options.plotting, "backend"), - reason="Currently installed pandas doesn't support plotting backends.", -) def test_pandas_equiv(pandas_fn, px_fn): pd.options.plotting.backend = "plotly" df = pd.DataFrame(np.random.randn(100, 4), columns=list("ABCD")).cumsum() assert pandas_fn(df) == px_fn(df) +@pytest.mark.skipif( + not hasattr(pd.options.plotting, "backend"), + reason="Currently installed pandas doesn't support plotting backends.", +) def test_pandas_example(): pd.options.plotting.backend = "plotly" ts = pd.Series(np.random.randn(1000), index=pd.date_range("1/1/2000", periods=1000))