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

Add LineCollection plot #7173

Open
wants to merge 122 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
122 commits
Select commit Hold shift + click to select a range
f01ce23
Add linecollection
Illviljan Oct 16, 2022
7025b99
Update dataarray_plot.py
Illviljan Oct 16, 2022
638a91d
add more lines
Illviljan Oct 16, 2022
2eed4d5
Merge branch 'main' into plot1d_lines
Illviljan Oct 17, 2022
cf0d4ae
Update dataarray_plot.py
Illviljan Oct 18, 2022
147f494
Merge branch 'main' into plot1d_lines
Illviljan Oct 27, 2022
a152fb9
Merge branch 'main' into plot1d_lines
Illviljan May 21, 2023
09c5c66
Merge branch 'main' into plot1d_lines
Illviljan May 21, 2023
8360175
Remove old code
Illviljan May 21, 2023
7a0a739
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 21, 2023
d51bf70
Update accessor.py
Illviljan May 21, 2023
93a132c
keep similar format as scatter
Illviljan May 21, 2023
ce4a806
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 21, 2023
2bd5aac
Update dataarray_plot.py
Illviljan May 21, 2023
dfc3bb8
keep same format as scatter
Illviljan May 21, 2023
079a6a7
Merge branch 'main' into plot1d_lines
Illviljan Sep 16, 2023
2e940c3
Fix lines plot
Illviljan Sep 16, 2023
7c102d5
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 16, 2023
789d6af
Update dataarray_plot.py
Illviljan Sep 16, 2023
3c4e442
Merge branch 'plot1d_lines' of https://github.com/Illviljan/xarray in…
Illviljan Sep 16, 2023
51742e2
Merge branch 'main' into plot1d_lines
Illviljan Sep 17, 2023
0cb969a
Update utils.py
Illviljan Sep 17, 2023
d8204e6
Attempt at hanlding coordinates with multiple dimensions
Illviljan Sep 17, 2023
edfa297
Merge branch 'main' into plot1d_lines
Illviljan Dec 10, 2023
4a1e2d6
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 10, 2023
35c402d
Merge branch 'main' into plot1d_lines
Illviljan Mar 10, 2024
baf93ab
Update test_plot.py
Illviljan Mar 10, 2024
d5467a6
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 10, 2024
6044e78
Update test_plot.py
Illviljan Mar 10, 2024
8dc66a9
Merge branch 'plot1d_lines' of https://github.com/Illviljan/xarray in…
Illviljan Mar 10, 2024
d9d0db4
merge tests
Illviljan Mar 10, 2024
0bac33a
Use similar format as scatter
Illviljan Mar 10, 2024
4bb57ca
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 10, 2024
d5fa2c5
Update utils.py
Illviljan Mar 10, 2024
45623a2
Merge branch 'plot1d_lines' of https://github.com/Illviljan/xarray in…
Illviljan Mar 10, 2024
79978a4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 10, 2024
29691d0
Update utils.py
Illviljan Mar 10, 2024
d9f0854
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 10, 2024
afc1c1b
Update utils.py
Illviljan Mar 10, 2024
8ece6a4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 10, 2024
bd11e62
Update utils.py
Illviljan Mar 10, 2024
e5f4b7e
Merge branch 'plot1d_lines' of https://github.com/Illviljan/xarray in…
Illviljan Mar 10, 2024
3e3fd8b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 10, 2024
f3f6554
Update utils.py
Illviljan Mar 10, 2024
6b70602
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 10, 2024
768f68e
Update utils.py
Illviljan Mar 10, 2024
b9af902
Update utils.py
Illviljan Mar 10, 2024
dcabb85
s can be float, no __len__ on those
Illviljan Mar 10, 2024
5690a4b
Update dataarray_plot.py
Illviljan Mar 10, 2024
2ff8742
Update dataarray_plot.py
Illviljan Mar 10, 2024
7bb8c32
Update dataarray_plot.py
Illviljan Mar 10, 2024
a43d685
Update dataarray_plot.py
Illviljan Mar 10, 2024
3ada357
add Hashable vs None ignores
Illviljan Mar 10, 2024
6911b66
Update utils.py
Illviljan Mar 10, 2024
33a151f
clean up
Illviljan Mar 10, 2024
499607b
Merge branch 'main' into plot1d_lines
Illviljan Mar 13, 2024
8910396
Fix color="k"
Illviljan Mar 13, 2024
6def426
cleanup
Illviljan Mar 14, 2024
ae3f623
Add tests for color and linestyle
Illviljan Mar 14, 2024
ae5bc23
Merge branch 'main' into plot1d_lines
Illviljan Mar 14, 2024
164d15e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 14, 2024
207133f
Update test_plot.py
Illviljan Mar 14, 2024
62bbcc8
Update test_plot.py
Illviljan Mar 14, 2024
dac8746
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 14, 2024
3578442
assert not needed
Illviljan Mar 20, 2024
d7b2c0a
Merge branch 'main' into plot1d_lines
Illviljan Mar 20, 2024
07fffb3
Update utils.py
Illviljan Mar 20, 2024
5626d73
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 20, 2024
98edb79
Update utils.py
Illviljan Mar 20, 2024
e90ef58
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 20, 2024
bee8b94
Update utils.py
Illviljan Mar 21, 2024
9f867cd
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 21, 2024
1da316e
Update utils.py
Illviljan Mar 21, 2024
e4aaaa8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 21, 2024
2917141
Merge branch 'main' into plot1d_lines
Illviljan Mar 22, 2024
fcad6de
Update utils.py
Illviljan Mar 22, 2024
89820a0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 22, 2024
aef553d
Merge branch 'main' into plot1d_lines
Illviljan Apr 5, 2024
0106bb7
Add some docs examples
Illviljan Apr 5, 2024
f08f8c5
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 5, 2024
d57b753
Update plotting.rst
Illviljan Apr 5, 2024
c281454
Merge branch 'plot1d_lines' of https://github.com/Illviljan/xarray in…
Illviljan Apr 5, 2024
532cb9d
Update plotting.rst
Illviljan Apr 5, 2024
50cd419
Update plotting.rst
Illviljan Apr 5, 2024
cc14075
Update plotting.rst
Illviljan Apr 6, 2024
59267ad
Update plotting.rst
Illviljan Apr 6, 2024
1720e0b
Update plotting.rst
Illviljan Apr 6, 2024
d45c819
Update plotting.rst
Illviljan Apr 6, 2024
9f1154a
Update api.rst
Illviljan Apr 6, 2024
659a9fe
improve docs
Illviljan Apr 6, 2024
8009145
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 6, 2024
78e26cb
Update __init__.py
Illviljan Apr 6, 2024
8737a1c
Merge branch 'plot1d_lines' of https://github.com/Illviljan/xarray in…
Illviljan Apr 6, 2024
f4c3c43
fix legend values
Illviljan Apr 6, 2024
bc433ab
Update api-hidden.rst
Illviljan Apr 6, 2024
08965fe
Update utils.py
Illviljan Apr 6, 2024
8b3558a
Add more legend labels tests
Illviljan Apr 6, 2024
7f1780f
Try without fix
Illviljan Apr 6, 2024
8a495b8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 6, 2024
7684c65
add fix
Illviljan Apr 6, 2024
971fb2e
mypy fixes
Illviljan Apr 6, 2024
c47b1ad
Make sure lines legend is correct
Illviljan Apr 7, 2024
30213b2
Update test_plot.py
Illviljan Apr 7, 2024
2bf943d
Update test_plot.py
Illviljan Apr 7, 2024
422b8da
Update test_plot.py
Illviljan Apr 7, 2024
0b16cf9
Update test_plot.py
Illviljan Apr 7, 2024
6e13194
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 7, 2024
c26233e
Update facetgrid.py
Illviljan Apr 7, 2024
10fac37
Update facetgrid.py
Illviljan Apr 7, 2024
a83b3be
Update dataarray_plot.py
Illviljan Apr 7, 2024
ae2d71f
Merge branch 'main' into plot1d_lines
Illviljan May 17, 2024
c3f461c
remove commented code
Illviljan May 17, 2024
dfdd221
Merge branch 'main' into plot1d_lines
Illviljan May 24, 2024
30e2356
Update xarray/plot/utils.py
Illviljan May 28, 2024
47956b4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 28, 2024
f284a1e
Merge branch 'main' into plot1d_lines
Illviljan Jun 23, 2024
f53da04
Update whats-new.rst
Illviljan Jun 23, 2024
0a20402
Add more docs
Illviljan Jun 23, 2024
b7c0365
Merge branch 'main' into plot1d_lines
Illviljan Jul 9, 2024
e4f5258
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 9, 2024
eda1d74
fix bad merge
Illviljan Jul 9, 2024
381ec22
Merge branch 'plot1d_lines' of https://github.com/Illviljan/xarray in…
Illviljan Jul 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/api-hidden.rst
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@
plot.imshow
plot.pcolormesh
plot.scatter
plot.lines
plot.surface

CFTimeIndex.all
Expand Down
2 changes: 2 additions & 0 deletions doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,7 @@ Dataset
:template: autosummary/accessor_method.rst

Dataset.plot.scatter
Dataset.plot.lines
Dataset.plot.quiver
Dataset.plot.streamplot

Expand All @@ -708,6 +709,7 @@ DataArray
DataArray.plot.pcolormesh
DataArray.plot.step
DataArray.plot.scatter
DataArray.plot.lines
DataArray.plot.surface


Expand Down
69 changes: 69 additions & 0 deletions doc/user-guide/plotting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,75 @@ And adding the z-axis
For more advanced scatter plots, we recommend converting the relevant data variables
to a pandas DataFrame and using the extensive plotting capabilities of ``seaborn``.

Lines
~~~~~

.. ipython:: python
:suppress:

plt.close("all")

:py:func:`xarray.plot.lines` calls matplotlib.collections.LineCollection under the hood,
allowing multiple lines being drawn efficiently. It uses similar arguments as
:py:func:`xarray.plot.scatter`.

Let's return to the air temperature dataset:

.. ipython:: python
:okwarning:

airtemps = xr.tutorial.open_dataset("air_temperature")
air = airtemps.air - 273.15
air.attrs = airtemps.air.attrs
air.attrs["units"] = "deg C"

@savefig lines_air_hue.png
air.isel(lon=10).plot.lines(x="time", hue="lat")

Make it a little more transparent:

.. ipython:: python
:okwarning:

@savefig lines_air_hue_alpha.png
air.isel(lon=10).plot.lines(x="time", hue="lat", alpha=0.2)

Zoom in a little on the x-axis, and compare a few latitudes and longitudes,
group them using ``hue`` and ``linewidth``. The ``linewidth`` kwarg works in
a similar way as ``markersize`` kwarg for scatter plots, it lets you vary the
line's size by variable value.

.. ipython:: python
:okwarning:

air_zoom = air.isel(time=slice(1200, 1500), lat=[5, 10, 15], lon=[10, 15])

@savefig lines_hue_linewidth.png
air_zoom.plot.lines(x="time", hue="lat", linewidth="lon", add_colorbar=False)

Lines can modify the linestyle but does not allow markers. Instead combine :py:func:`xarray.plot.lines`
with :py:func:`xarray.plot.scatter`:

.. ipython:: python
:okwarning:

air.isel(lat=10, lon=10)[:200].plot.lines(x="time", color="k", linestyle="dashed")
air.isel(lat=10, lon=10)[:200].plot.scatter(x="time", color="k", marker="^")
@savefig lines_linestyle_marker.png
plt.draw()


Switching to another dataset with more variables we can analyse in similar
fashion as :py:func:`xarray.plot.scatter`:

.. ipython:: python
:okwarning:

ds = xr.tutorial.scatter_example_dataset(seed=42)

@savefig lines_xyhuewidthrowcol.png
ds.plot.lines(x="A", y="B", hue="y", linewidth="x", row="x", col="w")

Quiver
~~~~~~

Expand Down
4 changes: 4 additions & 0 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ New Features
~~~~~~~~~~~~
- Allow chunking for arrays with duplicated dimension names (:issue:`8759`, :pull:`9099`).
By `Martin Raspaud <https://github.com/mraspaud>`_.
- Added new plot method `lines` which allows creating line plots efficiently in
a similiar manner to `scatter`. (:pull:`7173`)
By `Jimmy Westling <https://github.com/illviljan>`_.

- Extract the source url from fsspec objects (:issue:`9142`, :pull:`8923`).
By `Justus Magin <https://github.com/keewis>`_.

Expand Down
2 changes: 2 additions & 0 deletions xarray/plot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
hist,
imshow,
line,
lines,
pcolormesh,
plot,
step,
Expand All @@ -32,5 +33,6 @@
"pcolormesh",
"FacetGrid",
"scatter",
"lines",
"surface",
]
248 changes: 248 additions & 0 deletions xarray/plot/accessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,130 @@ def line(
def line(self, *args, **kwargs) -> list[Line3D] | FacetGrid[DataArray]:
return dataarray_plot.line(self._da, *args, **kwargs)

@overload
def lines( # type: ignore[misc,unused-ignore] # None is hashable :(
self,
*args: Any,
x: Hashable | None = None,
y: Hashable | None = None,
z: Hashable | None = None,
hue: Hashable | None = None,
hue_style: HueStyleOptions = None,
markersize: Hashable | None = None,
linewidth: Hashable | None = None,
figsize: Iterable[float] | None = None,
size: float | None = None,
aspect: float | None = None,
ax: Axes | None = None,
row: None = None, # no wrap -> primitive
col: None = None, # no wrap -> primitive
col_wrap: int | None = None,
xincrease: bool | None = True,
yincrease: bool | None = True,
add_legend: bool | None = None,
add_colorbar: bool | None = None,
add_labels: bool | Iterable[bool] = True,
add_title: bool = True,
subplot_kws: dict[str, Any] | None = None,
xscale: ScaleOptions = None,
yscale: ScaleOptions = None,
xticks: ArrayLike | None = None,
yticks: ArrayLike | None = None,
xlim: ArrayLike | None = None,
ylim: ArrayLike | None = None,
cmap=None,
vmin: float | None = None,
vmax: float | None = None,
norm: Normalize | None = None,
extend=None,
levels=None,
**kwargs: Any,
) -> LineCollection: ...

@overload
def lines(
self,
*args: Any,
x: Hashable | None = None,
y: Hashable | None = None,
z: Hashable | None = None,
hue: Hashable | None = None,
hue_style: HueStyleOptions = None,
markersize: Hashable | None = None,
linewidth: Hashable | None = None,
figsize: Iterable[float] | None = None,
size: float | None = None,
aspect: float | None = None,
ax: Axes | None = None,
row: Hashable | None = None,
col: Hashable, # wrap -> FacetGrid
col_wrap: int | None = None,
xincrease: bool | None = True,
yincrease: bool | None = True,
add_legend: bool | None = None,
add_colorbar: bool | None = None,
add_labels: bool | Iterable[bool] = True,
add_title: bool = True,
subplot_kws: dict[str, Any] | None = None,
xscale: ScaleOptions = None,
yscale: ScaleOptions = None,
xticks: ArrayLike | None = None,
yticks: ArrayLike | None = None,
xlim: ArrayLike | None = None,
ylim: ArrayLike | None = None,
cmap=None,
vmin: float | None = None,
vmax: float | None = None,
norm: Normalize | None = None,
extend=None,
levels=None,
**kwargs: Any,
) -> FacetGrid[DataArray]: ...

@overload
def lines(
self,
*args: Any,
x: Hashable | None = None,
y: Hashable | None = None,
z: Hashable | None = None,
hue: Hashable | None = None,
hue_style: HueStyleOptions = None,
markersize: Hashable | None = None,
linewidth: Hashable | None = None,
figsize: Iterable[float] | None = None,
size: float | None = None,
aspect: float | None = None,
ax: Axes | None = None,
row: Hashable, # wrap -> FacetGrid
col: Hashable | None = None,
col_wrap: int | None = None,
xincrease: bool | None = True,
yincrease: bool | None = True,
add_legend: bool | None = None,
add_colorbar: bool | None = None,
add_labels: bool | Iterable[bool] = True,
add_title: bool = True,
subplot_kws: dict[str, Any] | None = None,
xscale: ScaleOptions = None,
yscale: ScaleOptions = None,
xticks: ArrayLike | None = None,
yticks: ArrayLike | None = None,
xlim: ArrayLike | None = None,
ylim: ArrayLike | None = None,
cmap=None,
vmin: float | None = None,
vmax: float | None = None,
norm: Normalize | None = None,
extend=None,
levels=None,
**kwargs: Any,
) -> FacetGrid[DataArray]: ...

@functools.wraps(dataarray_plot.lines)
def lines(self, *args, **kwargs) -> LineCollection | FacetGrid[DataArray]:
return dataarray_plot.lines(self._da, *args, **kwargs)

@overload
def step( # type: ignore[misc,unused-ignore] # None is hashable :(
self,
Expand Down Expand Up @@ -923,6 +1047,130 @@ def __call__(self, *args, **kwargs) -> NoReturn:
"an explicit plot method, e.g. ds.plot.scatter(...)"
)

@overload
def lines( # type: ignore[misc,unused-ignore] # None is hashable :(
self,
*args: Any,
x: Hashable | None = None,
y: Hashable | None = None,
z: Hashable | None = None,
hue: Hashable | None = None,
hue_style: HueStyleOptions = None,
markersize: Hashable | None = None,
linewidth: Hashable | None = None,
figsize: Iterable[float] | None = None,
size: float | None = None,
aspect: float | None = None,
ax: Axes | None = None,
row: None = None, # no wrap -> primitive
col: None = None, # no wrap -> primitive
col_wrap: int | None = None,
xincrease: bool | None = True,
yincrease: bool | None = True,
add_legend: bool | None = None,
add_colorbar: bool | None = None,
add_labels: bool | Iterable[bool] = True,
add_title: bool = True,
subplot_kws: dict[str, Any] | None = None,
xscale: ScaleOptions = None,
yscale: ScaleOptions = None,
xticks: ArrayLike | None = None,
yticks: ArrayLike | None = None,
xlim: ArrayLike | None = None,
ylim: ArrayLike | None = None,
cmap=None,
vmin: float | None = None,
vmax: float | None = None,
norm: Normalize | None = None,
extend=None,
levels=None,
**kwargs: Any,
) -> LineCollection: ...

@overload
def lines(
self,
*args: Any,
x: Hashable | None = None,
y: Hashable | None = None,
z: Hashable | None = None,
hue: Hashable | None = None,
hue_style: HueStyleOptions = None,
markersize: Hashable | None = None,
linewidth: Hashable | None = None,
figsize: Iterable[float] | None = None,
size: float | None = None,
aspect: float | None = None,
ax: Axes | None = None,
row: Hashable | None = None,
col: Hashable, # wrap -> FacetGrid
col_wrap: int | None = None,
xincrease: bool | None = True,
yincrease: bool | None = True,
add_legend: bool | None = None,
add_colorbar: bool | None = None,
add_labels: bool | Iterable[bool] = True,
add_title: bool = True,
subplot_kws: dict[str, Any] | None = None,
xscale: ScaleOptions = None,
yscale: ScaleOptions = None,
xticks: ArrayLike | None = None,
yticks: ArrayLike | None = None,
xlim: ArrayLike | None = None,
ylim: ArrayLike | None = None,
cmap=None,
vmin: float | None = None,
vmax: float | None = None,
norm: Normalize | None = None,
extend=None,
levels=None,
**kwargs: Any,
) -> FacetGrid[DataArray]: ...

@overload
def lines(
self,
*args: Any,
x: Hashable | None = None,
y: Hashable | None = None,
z: Hashable | None = None,
hue: Hashable | None = None,
hue_style: HueStyleOptions = None,
markersize: Hashable | None = None,
linewidth: Hashable | None = None,
figsize: Iterable[float] | None = None,
size: float | None = None,
aspect: float | None = None,
ax: Axes | None = None,
row: Hashable, # wrap -> FacetGrid
col: Hashable | None = None,
col_wrap: int | None = None,
xincrease: bool | None = True,
yincrease: bool | None = True,
add_legend: bool | None = None,
add_colorbar: bool | None = None,
add_labels: bool | Iterable[bool] = True,
add_title: bool = True,
subplot_kws: dict[str, Any] | None = None,
xscale: ScaleOptions = None,
yscale: ScaleOptions = None,
xticks: ArrayLike | None = None,
yticks: ArrayLike | None = None,
xlim: ArrayLike | None = None,
ylim: ArrayLike | None = None,
cmap=None,
vmin: float | None = None,
vmax: float | None = None,
norm: Normalize | None = None,
extend=None,
levels=None,
**kwargs: Any,
) -> FacetGrid[DataArray]: ...

@functools.wraps(dataset_plot.lines)
def lines(self, *args, **kwargs) -> LineCollection | FacetGrid[DataArray]:
return dataset_plot.lines(self._ds, *args, **kwargs)

@overload
def scatter( # type: ignore[misc,unused-ignore] # None is hashable :(
self,
Expand Down
Loading
Loading