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.12k stars 108 forks source link

Grid doesn't show on top of images #314

Closed tomchor closed 5 years ago

tomchor commented 5 years ago

When I set grid=True for line plots it works as expected. However, the same doesn't happen for heatmaps. The following example doesn't throw any warnings about invalid keywords and produces a plot without any grid.

import xarray as xr
import hvplot.xarray
air_ds = xr.tutorial.open_dataset('air_temperature').load()
air_ds.isel(time=0).hvplot(width=500, clim=(230, 300), grid=True)

The following MWE (where I force the data to be plotted as lines) plots the grid successfully:

import xarray as xr
import hvplot.xarray
air_ds = xr.tutorial.open_dataset('air_temperature').load()
air_ds.isel(time=0).hvplot.line(width=500, clim=(230, 300), grid=True)

Relevant versions:

hvplot: 0.4.0 bokeh: 1.3.4 holoviews: 1.12.5

jsignell commented 5 years ago

If you change the alpha (air_ds.isel(time=0).hvplot(width=500, clim=(230, 300), grid=True, alpha=0.5)) you'll see that the grid is there, it is just under the data layer. This is the same behavior that we have for grids on scatter plots or line plots, the difference is that for those other plot types, the plot elements are sparse enough that you can still see the grid.

Changing the level that the gridlines display at would require a change in bokeh and I'm not convinced it'd be that useful or desirable.

To achieve what you are talking about you might try using a quadmesh instead: air_ds.isel(time=0).hvplot.quadmesh(width=500, clim=(230, 300), grid=True)

tomchor commented 5 years ago

@jsignell So that's the default behavior for bokeh? I know nothing of Bokeh, but that doesn't seem like a very useful behavior. Is there a reason why it's like this?

Unfortunately quadmesh doesn't like give off the effect I'm looking for since it just makes the space between each grid point visible. Plus, when your data is high-res it becomes a nightmare. Is there no way to reproduce the behavior of Matplotlib using bokeh?

ahuang11 commented 5 years ago

If this is a geo plot, you can do

import xarray as xr
import hvplot.xarray
import geoviews as gv
air_ds = xr.tutorial.open_dataset('air_temperature').load()
air_ds.isel(time=0).hvplot(width=500, clim=(230, 300), geo=True) * gv.feature.grid()
jsignell commented 5 years ago

Maybe holoviews could implement a similar .grid()? Or bokeh could have a z_level argument for grid options.

tomchor commented 5 years ago

Specifically for my case, it isn't a geo plot, so I can't use geoviews. But like @jsignell I think that it would be useful to have at least some way to plot grids on top of heatmaps.

ahuang11 commented 5 years ago

Another way is to lower opacity of your heatmap and change color of grid (if thats possible)

jsignell commented 5 years ago

I opened an issue on bokeh to capture this. I agree that the current behavior isn't desirable.

tomchor commented 5 years ago

@jsignell I know this issue is closed, but I found no way in the hvplot docs to apply the solution for putting the grid above the plot that was suggested at the Bokeh issue you created. Is there a way to do it? Or am I just stuck without grids for the time being?

jsignell commented 5 years ago

HoloViews exposes the grid style options, but not the bokeh rendering level. So to access that you need a hook :

import xarray as xr
import hvplot.xarray
air_ds = xr.tutorial.open_dataset('air_temperature').load()

def hook(plot, element):
    """Set the image renderer to happen under the grid lines"""
    plot.handles['glyph_renderer'].level = 'image'

plot = air_ds.isel(time=0).hvplot(width=500, clim=(230, 300), grid=True)
plot.opts(hooks=[hook], gridstyle=dict(grid_line_color='white', grid_line_width=2))
Screen Shot 2019-09-27 at 1 22 26 PM

You can change the grid style however you like. See https://bokeh.pydata.org/en/latest/docs/user_guide/styling.html#grids for ideas

tomchor commented 5 years ago

@jsignell I see. Great, thanks!