Skip to content

Conversation

@Illviljan
Copy link
Contributor

@Illviljan Illviljan commented Oct 16, 2022

This adds a line plotter based on LineCollections, called .lines.

I wanted to replace darray.plot() with using LineCollection instead. But unfortunately due to how many cases are supported (and tested in xarray) darray.plot() will continue using plt.plot.

Examples:

https://www.reddit.com/r/dataisbeautiful/comments/1d4ahr1/oc_north_atlantic_sea_surface_temperature_anomaly/

Got this working with xarray:

# https://www.reddit.com/r/dataisbeautiful/comments/1d4ahr1/oc_north_atlantic_sea_surface_temperature_anomaly/#lightbox
# https://github.com/afinemax/climate_change_bot/blob/main/bot.py


import requests

import numpy as np
import matplotlib.pyplot as plt
import xarray as xr


def download_json(url):
    try:
        response = requests.get(url)
        response.raise_for_status()  # Raise an exception for unsuccessful responses (4xx, 5xx)
        json_data = response.json()
        return json_data
    except requests.exceptions.RequestException as e:
        print(f"Error downloading JSON: {e}")
        return None


url = r"https://climatereanalyzer.org/clim/sst_daily/json/oisst2.1_natlan1_sst_day.json"
sst_daily_data = download_json(url)


data = []
years = []
for i in range(len(sst_daily_data) - 3):
    years.append((sst_daily_data[i]["name"]))
    data.append(sst_daily_data[i]["data"])

# convert data from list into nd arr
data = np.asarray(data, dtype=float)  # first index is year, 2nd index is day

# Datetimes not working for some unrelated reason:
# ds = xr.Dataset(
#     data_vars=dict(temperature=(("year", "day"), data)),
#     coords=dict(
#         year=np.array(dict_names, dtype="datetime64[D]"),
#         day=np.arange(data.shape[-1], dtype="timedelta64[D]"),
#     ),
# )
ds = xr.Dataset(
    data_vars=dict(
        temperature=(
            ("year", "day"),
            data,
            dict(
                long_name="Daily North Atlantic (0-60N) Sea Surface Temperature (SST)",
                units="degC",
            ),
        )
    ),
    coords=dict(
        year=np.array(years, dtype=int),
        day=np.arange(data.shape[-1], dtype=int),
    ),
)

plt.figure()
ds.plot.lines(x="day", y="temperature", hue="year")

image

Calling it lines since scatter is not called path_collection:

  • PathCollection (Very low-level, e.g. no datetime handling) -> plt.scatter (Handles datetime etc.)-> xr.plot.scatter
  • LineCollection (Very low-level, e.g. no datetime handling) -> _line (Handles datetime etc. Pretty much a copy of plt.scatter) -> xr.plot.lines

Seaborns new object-based plotting uses lines as well with similar argument:
https://seaborn.pydata.org/generated/seaborn.objects.Line.html
https://seaborn.pydata.org/generated/seaborn.objects.Lines.html

xref:
#4820
#5622

@Illviljan
Copy link
Contributor Author

Illviljan commented Oct 17, 2022

Scatter vs. Lines:

image

ds = xr.tutorial.scatter_example_dataset(seed=42)
hue_ = "y"
x_ = "y"
size_="y"
z_ = "z"

fig = plt.figure()
ax = fig.add_subplot(1, 2, 1, projection='3d')
ds.A.sel(w="one").plot.lines(x=x_, z=z_, hue=hue_, linewidth=size_, ax=ax)
ax = fig.add_subplot(1, 2, 2, projection='3d')
ds.A.sel(w="one").plot.scatter(x=x_, z=z_, hue=hue_, markersize=size_, ax=ax)

@Illviljan
Copy link
Contributor Author

my only concern is the one character difference between .line and .lines. Shall we call it line_collection instead? Ideally we would have only one of these but I can see its hard to do that now, given how complex the plotting module is.

line_collection implies a more basic version in my mind:

  • PathCollection (Very low-level, e.g. no datetime handling) -> plt.scatter (Handles datetime etc.)-> xr.plot.scatter
  • LineCollection (Very low-level, e.g. no datetime handling) -> _line (Handles datetime etc. Pretty much a copy of plt.scatter) -> xr.plot.lines

Seaborns new object-based plotting uses lines as well with similar argument, so I don't feel too worried anymore:
https://seaborn.pydata.org/generated/seaborn.objects.Line.html
https://seaborn.pydata.org/generated/seaborn.objects.Lines.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

plan to merge Final call for comments topic-plotting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants