holoviz / geoviews

Simple, concise geographical visualization in Python
http://geoviews.org
BSD 3-Clause "New" or "Revised" License
590 stars 76 forks source link

How to plot unevenly spaced data? #150

Closed pgierz closed 6 years ago

pgierz commented 6 years ago

I have a dataset of the dimensions (time, lat, lon) for instance like this:

<xarray.DataArray 'temp2' (time: 1200, lat: 48, lon: 96)>
dask.array<shape=(1200, 48, 96), dtype=float32, chunksize=(1, 48, 96)>
Coordinates:
  * lon      (lon) float64 0.0 3.75 7.5 11.25 15.0 18.75 22.5 26.25 30.0 ...
  * lat      (lat) float64 87.16 83.48 79.78 76.07 72.36 68.65 64.94 61.23 ...
  * time     (time) float64 2.6e+07 2.6e+07 2.6e+07 2.6e+07 2.6e+07 2.6e+07 ...
Attributes:
    long_name:  2m temperature
    units:      K
    code:       167
    table:      128
    grid_type:  gaussian

If I try to plot this with gv.Image, I get the following error:

ValueError: Image dimension lat is not evenly sampled to rtol tolerance of 1e-05, please use the QuadMesh element for unevenly or irregularly sampled data.

However, my installation of geoviews does not have the QuadMesh element available. I also tried FilledContours, but got the following:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-13-6dbf48ac710e> in <module>()
      1 dataset = gv.Dataset(Eem125_echam, kdims=['lon', 'lat', 'time'], crs=crs.PlateCarree())
----> 2 dataset.to(gv.FilledContours, ['lon', 'lat'], ['temp2'], ['time']) * gf.coastline()

~/anaconda3/lib/python3.6/site-packages/geoviews/element/__init__.py in __call__(self, *args, **kwargs)
     25         if 'crs' not in kwargs and issubclass(group_type, _Element):
     26             kwargs['crs'] = self._element.crs
---> 27         return super(GeoConversion, self).__call__(*args, **kwargs)
     28 
     29     def linecontours(self, kdims=None, vdims=None, mdims=None, **kwargs):

~/anaconda3/lib/python3.6/site-packages/holoviews/core/data/__init__.py in __call__(self, new_type, kdims, vdims, groupby, sort, **kwargs)
    144             return element.sort() if sort else element
    145         group = selected.groupby(groupby, container_type=HoloMap,
--> 146                                  group_type=new_type, **params)
    147         if sort:
    148             return group.map(lambda x: x.sort(), [new_type])

~/anaconda3/lib/python3.6/site-packages/holoviews/core/data/__init__.py in groupby(self, dimensions, container_type, group_type, dynamic, **kwargs)
    544 
    545         return self.interface.groupby(self, dim_names, container_type,
--> 546                                       group_type, **kwargs)
    547 
    548     def __len__(self):

~/anaconda3/lib/python3.6/site-packages/holoviews/core/data/xarray.py in groupby(cls, dataset, dimensions, container_type, group_type, **kwargs)
    221                 if drop_dim:
    222                     v = v.to_dataframe().reset_index()
--> 223                 data.append((k, group_type(v, **group_kwargs)))
    224         else:
    225             unique_iters = [cls.values(dataset, d, False) for d in group_by]

~/anaconda3/lib/python3.6/site-packages/geoviews/element/geo.py in __init__(self, data, kdims, vdims, **kwargs)
     88         elif crs:
     89             kwargs['crs'] = crs
---> 90         super(_Element, self).__init__(data, kdims=kdims, vdims=vdims, **kwargs)
     91 
     92 

~/anaconda3/lib/python3.6/site-packages/holoviews/element/raster.py in __init__(self, data, kdims, vdims, bounds, extents, xdensity, ydensity, rtol, **params)
    286         # Ensure coordinates are regularly sampled
    287         validate_regular_sampling(self, 0, self.rtol)
--> 288         validate_regular_sampling(self, 1, self.rtol)
    289 
    290 

~/anaconda3/lib/python3.6/site-packages/holoviews/element/util.py in validate_regular_sampling(img, dimension, rtol)
    321     if len(vals) > 1 and np.abs(vals.min()-vals.max()) > diffs.min()*rtol:
    322         raise ValueError(msg.format(clsname=type(img).__name__,
--> 323                                     dim=dim, rtol=rtol))

ValueError: FilledContours dimension lat is not evenly sampled to rtol tolerance of 1e-05, please use the QuadMesh element for unevenly or irregularly sampled data.

PS: I'm not sure if the issue tracker is the right place to ask "How do I..." questions. If not, could you please let me know where it would be more appropriate? (or maybe write a small note in the repo's readme)

Thanks for the help! Paul

philippjfr commented 6 years ago

@pgierz Thanks for filing the issue, there will be a GeoViews release in a day or two which will contain the QuadMesh element. If you just want a fairly rough plot you could also try increasing the rtol value by passing it into the constructor.

In general StackOverflow would be preferred for usage questions but in this case an issue or a question on our Gitter channel is fine.

pgierz commented 6 years ago

Ok great, thanks! The following seems to have worked:

%%opts Image [colorbar=True fig_size=200] (cmap='viridis')
dataset = gv.Dataset(Eem125_echam, kdims=['lon', 'lat', 'time'], crs=crs.PlateCarree())
dataset.to(gv.Image, ['lon', 'lat'], ['temp2'], ['time'], rtol=5) * gf.coastline()