holoviz / hvplot

A high-level plotting API for pandas, dask, xarray, and networkx built on HoloViews
https://hvplot.holoviz.org
BSD 3-Clause "New" or "Revised" License
1.13k stars 109 forks source link

Plotting with coordinates that have different numbers of dimensions using xarray.hvplot #244

Closed hetland closed 5 years ago

hetland commented 5 years ago

There is an error in plotting coordinates with multiple dimensions using xarray.hvplot. xarray.plot (and also matplotlib) have the correct behavior. Here is some code to demonstrate the issue.

import numpy as np
import xarray as xr
import hvplot.xarray
import pandas as pd

import matplotlib.pyplot as plt
%matplotlib inline

# create an example dataset
dates = pd.date_range('2000-01-01', '2001-12-31', name='time')
times = dates - dates[0]

x = np.linspace(0, 10, 101)

h = np.linspace(3, 7, 101)
s = np.linspace(0, 1, 51)
z = s[:, np.newaxis] * h[np.newaxis, :]

data = (np.sin(x) * np.cos(z)) * np.cos(np.asarray(times.days[:, np.newaxis, np.newaxis]))

# construct xarray dataset
ds = xr.Dataset({'data': (('time', 's', 'x'), data)}, 
                {'time':dates, 'x':x, 's':s, 'z':(('s', 'x'), z)})

Matplotlib does the right thing using the raw numpy arrays:

# plot an example time slice
plt.pcolormesh(x, z, data[0])

xarray.plot also does the right thing:

ds.data.sel(time='2001-08-07').plot(x='x', y='z')

xarray.hvplot fails:

ds.hvplot.quadmesh(x='x', y='z')

Making a dummy 2d coordinate for x fixes things, and shows the functionality that users probably expect:

x2d = x*np.ones_like(z)
ds.coords['x2d'] = xr.DataArray(x2d, (ds.s, ds.x))
ds.data.hvplot.quadmesh(x='x2d', y='z', clim=(-2,2))

A simple fix could be to do a ones_like broadcast within hvplot when coordinates don't match, like presented in the last example, to ensure coordinates have the same size and shape.

rsignell-usgs commented 5 years ago

I'm running into this problem as well for ROMS ocean model examples