holoviz / geoviews

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

Layout doesn't respect projection opts #469

Closed suvarchal closed 4 years ago

suvarchal commented 4 years ago

ALL software version info

('geoviews', '1.8.1')
('bokeh', '2.0.2')
('cartopy', '0.17.0')

Description of expected behavior and the observed behavior

Wish laying out different projections of data is as simple as shown in documentation

Complete, minimal, self-contained example code that reproduces the issue

import geoviews as gv
import bokeh
import cartopy, cartopy.crs as crs
import xarray as xr
import numpy as np
print(('geoviews', gv.__version__),
      ('bokeh', bokeh.__version__),
      ('cartopy', cartopy.__version__), sep = '\n')
gv.extension('bokeh') # using matplotlib backend, the issue remains the same.

##### generate dummy global data
lats = np.arange(-90,90,20)
lons = np.arange(-180,180,20)
data = xr.DataArray(np.random.random(size=(lons.shape[0],lats.shape[0])),
                    coords={'lon':lons, 'lat':lats}, dims=['lon','lat'], name='test_da')

projections = [crs.RotatedPole, crs.LambertCylindrical, crs.Geostationary, 
               crs.AzimuthalEquidistant, crs.OSGB, crs.EuroPP, crs.Gnomonic,
               crs.Mollweide, crs.OSNI, crs.Miller, crs.InterruptedGoodeHomolosine,
               crs.SouthPolarStereo,  crs.Orthographic, crs.NorthPolarStereo, crs.Robinson,
               crs.LambertConformal, crs.AlbersEqualArea]

plot = gv.Points(data,kdims=['lon','lat'], vdims=['test_da']) # issue remains same with Quadmesh 
projection_layout = gv.Layout([plot.opts(projection=p()) 
                               for p in projections[3:8]]).cols(3) # subset of projections for quicker output
projection_layout

projection_layout

projection_AzimuthalE = plot.opts(projection=projections[3]())
projection_AzimuthalE # works 

plot_azimuthal

jlstevens commented 4 years ago

Thanks @suvarchal for the issue! Have you tried using clone=True in the .opts calls? You need to clone in order to apply the different options to the same Points object as otherwise, .opts simply changes the object in place. This is documented on this page.

suvarchal commented 4 years ago

@jlstevens , oops my bad, looking at https://geoviews.org/user_guide/Projections.html#Projecting-with-bokeh, it is almost tempting to do with other elements, now I see the trick there was relabel that created a new instance.

In general, I wonder isn't it better to always return a clone/new instance when a different projection is used? or is there a reason not to do it.

jlstevens commented 4 years ago

In general, I wonder isn't it better to always return a clone/new instance when a different projection is used?

HoloViews (and therefore Geoviews) has valid cases for setting options both with and without cloning. As such we leave this step up to the user and we generally avoid domain specific logic about when or when not to clone. I would say it is working as intended but perhaps the docs aren't clear enough of this issue. We would be very happy to hear any suggestions on improving the docs!