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

Refactor line plotting #4866

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open

Refactor line plotting #4866

wants to merge 6 commits into from

Conversation

dcherian
Copy link
Contributor

@dcherian dcherian commented Feb 5, 2021

Refactors line plotting to use a _plot1d decorator.

Next i'll use this decorator on hist so we can "facet" and "hue" histograms.

see #4288

@dcherian dcherian changed the title Refactor _infer_line_data Refactor line plotting Feb 5, 2021
Copy link
Contributor

@Illviljan Illviljan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it might be for a future PR but I think lineplots should support colorbars and linewidth:

Line plot with linewidth option and colorbar
def _lineplot(ds, x, y, hue, linewidth):
    if len(ds[y].dims) > 3:
        raise NotImplementedError("too many dims.")

    fig, ax = plt.subplots(1, 1)
    for i, width in enumerate(ds[linewidth]):
        # Filter along linewidth:
        dsi = ds.isel(**{linewidth: i})

        # Values to plot:
        xplt = dsi[x]

        # if xplt has no dims:
        (xdim,) = xplt.dims
        (huedim,) = dsi[hue].dims
        yplt = dsi[y].transpose(..., xdim, huedim)

        # Set plot properties:
        len_lines = len(ds[hue])
        cmap = plt.get_cmap("viridis", len_lines)
        colors = plt.cycler(color=cmap(np.arange(len_lines)))
        lw = plt.cycler(lw=[1 + i * 3])
        ax.set_prop_cycle(colors * lw)

        # p = xr.broadcast(xplt, yplt)
        plt.plot(xplt, yplt, label=width.values)
        plt.legend()

    # ax.plot doesn't return a mappable that fig.colorbar can parse. Create
    # one and return that one instead:
    norm = plt.Normalize(vmin=ds[hue].min(), vmax=ds[hue].max())
    primitive = plt.cm.ScalarMappable(cmap=plt.get_cmap("viridis"), norm=norm)
    fig.colorbar(mappable=primitive)

    return fig, ax

ds = xr.tutorial.scatter_example_dataset()
ds1 = ds.sel(z=0)
_lineplot(ds=ds1, x="y", y="A", hue="w", linewidth="x")

I've been trying to move ds.plot.scatter to the dataarray side so I have been playing around with a similar decorator as your _plot1d. It proved quite tricky for me to make the different primitives fit similar code. This one is a bit different and maybe it bypasses some of those issues I had. Just something to keep in mind.

xarray/plot/plot.py Outdated Show resolved Hide resolved
xarray/plot/plot.py Outdated Show resolved Hide resolved
xarray/plot/plot.py Show resolved Hide resolved
xarray/plot/plot.py Outdated Show resolved Hide resolved
xarray/plot/plot.py Outdated Show resolved Hide resolved
dcherian and others added 2 commits February 9, 2021 12:26
Co-authored-by: Illviljan <14371165+Illviljan@users.noreply.github.com>
Co-authored-by: Illviljan <14371165+Illviljan@users.noreply.github.com>
@TomNicholas TomNicholas mentioned this pull request Apr 29, 2021
13 tasks
Copy link
Collaborator

@mathause mathause left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 on merging just after the release - although I must say I don't do a lot of plotting with master. pity the signatures are different.

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

Successfully merging this pull request may close these issues.

None yet

4 participants