Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(python): add plot namespace (which defers to hvplot) #13238

Merged
merged 22 commits into from
Dec 31, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2619c8a
add plot namespace which defers to hvplot
MarcoGorelli Dec 24, 2023
4805791
plotting -> plot
MarcoGorelli Dec 27, 2023
648c16f
Merge remote-tracking branch 'upstream/main' into hvplot-backend
MarcoGorelli Dec 27, 2023
fe8729d
lint
MarcoGorelli Dec 27, 2023
4123a73
Merge remote-tracking branch 'upstream/main' into hvplot-backend
MarcoGorelli Dec 28, 2023
ff7aaa6
add tests for series.hist and unsupported dtype
MarcoGorelli Dec 28, 2023
019bcb9
add Series.plot to docs
MarcoGorelli Dec 28, 2023
0506a16
Merge remote-tracking branch 'upstream/main' into hvplot-backend
MarcoGorelli Dec 28, 2023
cde1728
set 0.9.1 as minimum hvplot version
MarcoGorelli Dec 28, 2023
335c8c4
fixup docs build
MarcoGorelli Dec 28, 2023
2d99d1a
typo + missing docs pages
MarcoGorelli Dec 28, 2023
af60d9a
fix docs build
MarcoGorelli Dec 28, 2023
28865de
no need to require hvplot for docs
MarcoGorelli Dec 28, 2023
c3ab5e6
skip plot doctest
MarcoGorelli Dec 28, 2023
e0af814
Merge remote-tracking branch 'upstream/main' into hvplot-backend
MarcoGorelli Dec 29, 2023
56612b3
raise if hvplot not installed or isnt >=0.9.1
MarcoGorelli Dec 30, 2023
0a4ae04
Merge remote-tracking branch 'upstream/main' into hvplot-backend
MarcoGorelli Dec 30, 2023
3696df4
use hvplot post_patch
MarcoGorelli Dec 31, 2023
ab84eb1
lint
MarcoGorelli Dec 31, 2023
19aca75
simplify, remove holoviews from dependencies.py
MarcoGorelli Dec 31, 2023
30e4e01
remove final holoviews
MarcoGorelli Dec 31, 2023
bba5c5a
link to PR comment, add TODO
MarcoGorelli Dec 31, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,13 @@ Install Polars with all optional dependencies.

```sh
pip install 'polars[all]'
pip install 'polars[numpy,pandas,pyarrow]' # install a subset of all optional dependencies
```

You can also install the dependencies directly.
You can also install a subset of all optional dependencies.

```sh
pip install 'polars[numpy,pandas,pyarrow]'
```

| Tag | Description |
| ---------- | ---------------------------------------------------------------------------- |
Expand All @@ -209,6 +212,7 @@ You can also install the dependencies directly.
| openpyxl | Support for reading from Excel files with native types |
| deltalake | Support for reading from Delta Lake Tables |
| pyiceberg | Support for reading from Apache Iceberg tables |
| plot | Support for plot functions on Dataframes |
| timezone | Timezone support, only needed if are on Python<3.9 or you are on Windows |

Releases happen quite often (weekly / every few days) at the moment, so updating polars regularly to get the latest bugfixes / features might not be a bad idea.
Expand Down
1 change: 1 addition & 0 deletions docs/user-guide/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pip install 'polars[numpy,fsspec]'
| connectorx | Support for reading from SQL databases |
| xlsx2csv | Support for reading from Excel files |
| deltalake | Support for reading from Delta Lake Tables |
| plot | Support for plotting Dataframes |
| timezone | Timezone support, only needed if 1. you are on Python < 3.9 and/or 2. you are on Windows, otherwise no dependencies will be installed |

### Rust
Expand Down
1 change: 1 addition & 0 deletions py-polars/docs/source/reference/dataframe/attributes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Attributes
DataFrame.dtypes
DataFrame.flags
DataFrame.height
DataFrame.plot
DataFrame.schema
DataFrame.shape
DataFrame.width
1 change: 1 addition & 0 deletions py-polars/docs/source/reference/dataframe/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This page gives an overview of all public DataFrame methods.
group_by
modify_select
miscellaneous
plotting

.. currentmodule:: polars

Expand Down
44 changes: 44 additions & 0 deletions py-polars/docs/source/reference/dataframe/plotting.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
========
Plotting
========

Polars does not implement plotting logic itself, but instead defers to
hvplot. Please see the `hvplot reference gallery <https://hvplot.holoviz.org/reference/index.html>`_
for more information and documentation.

Examples
--------
Scatter plot:

.. code-block:: python

df = pl.DataFrame(
{
"length": [1, 4, 6],
"width": [4, 5, 6],
"species": ["setosa", "setosa", "versicolor"],
}
)
df.plot.scatter(x="length", y="width", by="species")

Line plot:

.. code-block:: python

from datetime import date
df = pl.DataFrame(
{
"date": [date(2020, 1, 2), date(2020, 1, 3), date(2020, 1, 3)],
"stock_1": [1, 4, 6],
"stock_2": [1, 5, 2],
}
)
df.plot.line(x="date", y=["stock_1", "stock_2"])

For more info on what you can pass, you can use ``hvplot.help``:

.. code-block:: python

import hvplot
hvplot.help('scatter')

51 changes: 50 additions & 1 deletion py-polars/polars/dataframe/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ class DataFrame:

"""

_accessors: ClassVar[set[str]] = set()
_accessors: ClassVar[set[str]] = {"plot"}

def __init__(
self,
Expand Down Expand Up @@ -1116,6 +1116,55 @@ def _replace(self, column: str, new_column: Series) -> Self:
self._df.replace(column, new_column._s)
return self

@property
def plot(self) -> Any:
"""
Create a plot namespace.

Polars does not implement plotting logic itself, but instead defers to
hvplot. Please see the `hvplot reference gallery <https://hvplot.holoviz.org/reference/index.html>`_
for more information and documentation.

Examples
--------
Scatter plot:

>>> df = pl.DataFrame(
... {
... "length": [1, 4, 6],
... "width": [4, 5, 6],
... "species": ["setosa", "setosa", "versicolor"],
... }
... )
>>> df.plot.scatter(x="length", y="width", by="species") # doctest: +SKIP

Line plot:

>>> from datetime import date
>>> df = pl.DataFrame(
... {
... "date": [date(2020, 1, 2), date(2020, 1, 3), date(2020, 1, 3)],
... "stock_1": [1, 4, 6],
... "stock_2": [1, 5, 2],
... }
... )
>>> df.plot.line(x="date", y=["stock_1", "stock_2"]) # doctest: +SKIP

For more info on what you can pass, you can use ``hvplot.help``:

>>> import hvplot # doctest: +SKIP
>>> hvplot.help("scatter") # doctest: +SKIP
"""
try:
import hvplot.polars # noqa: F401
stinodego marked this conversation as resolved.
Show resolved Hide resolved
except ModuleNotFoundError:
raise ModuleNotFoundError(
"hvplot is not installed, or is older than version 0.9.0.\n\n"
"Please see https://hvplot.holoviz.org/getting_started/installation.html "
"for installation instructions."
) from None
stinodego marked this conversation as resolved.
Show resolved Hide resolved
return self.hvplot # type: ignore[attr-defined]

@property
def shape(self) -> tuple[int, int]:
"""
Expand Down
2 changes: 2 additions & 0 deletions py-polars/polars/utils/show_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def show_versions() -> None:
connectorx: 0.3.2
deltalake: 0.13.0
fsspec: 2023.10.0
hvplot: 0.9.0
gevent: 23.9.1
matplotlib: 3.8.2
numpy: 1.26.2
Expand Down Expand Up @@ -66,6 +67,7 @@ def _get_dependency_info() -> dict[str, str]:
"deltalake",
"fsspec",
"gevent",
"hvplot",
"matplotlib",
"numpy",
"openpyxl",
Expand Down
4 changes: 3 additions & 1 deletion py-polars/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ connectorx = ["connectorx >= 0.3.2"]
deltalake = ["deltalake >= 0.14.0"]
fsspec = ["fsspec"]
gevent = ["gevent"]
plot = ["hvplot >= 0.9.0"]
matplotlib = ["matplotlib"]
numpy = ["numpy >= 1.16.0"]
openpyxl = ["openpyxl >= 3.0.0"]
Expand All @@ -58,7 +59,7 @@ timezone = ["backports.zoneinfo; python_version < '3.9'", "tzdata; platform_syst
xlsx2csv = ["xlsx2csv >= 0.8.0"]
xlsxwriter = ["xlsxwriter"]
all = [
"polars[pyarrow,pandas,numpy,fsspec,connectorx,xlsx2csv,deltalake,timezone,matplotlib,pydantic,pyiceberg,sqlalchemy,xlsxwriter,adbc,cloudpickle,gevent]",
"polars[pyarrow,pandas,numpy,fsspec,plot,connectorx,xlsx2csv,deltalake,timezone,pydantic,pyiceberg,sqlalchemy,xlsxwriter,adbc,cloudpickle,gevent]",
]

[tool.maturin]
Expand Down Expand Up @@ -88,6 +89,7 @@ module = [
"ezodf.*",
"fsspec.*",
"gevent",
"hvplot.*",
"matplotlib.*",
"moto.server",
"openpyxl",
Expand Down
4 changes: 3 additions & 1 deletion py-polars/requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ dataframe-api-compat >= 0.1.6
pyiceberg >= 0.5.0
# Csv
zstandard
# Other
# Plotting
hvplot>=0.9.0
matplotlib
# Other
gevent

# -------
Expand Down
23 changes: 23 additions & 0 deletions py-polars/tests/unit/namespaces/test_plot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from datetime import date

import polars as pl


def test_plot_namespace() -> None:
stinodego marked this conversation as resolved.
Show resolved Hide resolved
df = pl.DataFrame(
{
"length": [1, 4, 6],
"width": [4, 5, 6],
"species": ["setosa", "setosa", "versicolor"],
}
)
df.plot.scatter(x="length", y="width", by="species")

df = pl.DataFrame(
{
"date": [date(2020, 1, 2), date(2020, 1, 3), date(2020, 1, 3)],
"stock_1": [1, 4, 6],
"stock_2": [1, 5, 2],
}
)
df.plot.line(x="date", y=["stock_1", "stock_2"])