Skip to content

Instantly share code, notes, and snippets.

@cwood1967
Created January 17, 2020 18:04
Show Gist options
  • Save cwood1967/f03ef2b48a1bdd080666edec25907c74 to your computer and use it in GitHub Desktop.
Save cwood1967/f03ef2b48a1bdd080666edec25907c74 to your computer and use it in GitHub Desktop.
import numpy as np
import pandas as pd
from holoviews import opts
import holoviews as hv
from holoviews import streams
import datashader
import xarray as xr
import hvplot.xarray
hv.extension('bokeh','matplotlib')
## this is the callback for when a rectangle is created
## it plots the mean intensity over time for the recangle
def roi_curves(data):
## data contains all of the rectangles on the image/canvas
## rectangles are defined by (x0, y0), (x1, y1)
## all rectangles x0s are in a list, all y0s are in a list, ...
## if using in a notebook, open developer tools to see the print
print(data)
## if data is empty return
if not data or not any(len(d) for d in data.values()):
return hv.NdOverlay({0:hv.Curve([], 't', 'intensity')})
## empty dictionary to of curves
curves = {}
data = zip(data['x0'], data['x1'], data['y0'], data['y1'])
for i, (x0, x1, y0, y1) in enumerate(data):
## selection is the area in the recangle
selection = dxp.loc[{'x':slice(x0,x1), 'y':slice(y0,y1), 'c':'gfp'}]
## aggregate with mean over remaining dimension
## will be time in this case
cagg = selection.mean(dim=['x', 'y'])
print(i, (x0, x1, y0, y1))
## add
curves[i] = hv.Curve(cagg)
return hv.NdOverlay(curves)
### dxp is an xarray DataArray
z =dxp.hvplot.image(x='x', y='y', cmap='viridis', colorbar=True,dynamic=True)
## polys holds the rectangle objects
polys = hv.Polygons([])
box_stream = streams.BoxEdit(source=polys)
### dynamic map to update the intensity vs time plots
dmap = hv.DynamicMap(roi_curves, streams=[box_stream])
## set default holoviews/bokeh options
opts.defaults(
opts.GridSpace(shared_xaxis=True, shared_yaxis=True),
opts.Image(cmap='viridis', width=562, height=512),
opts.Labels(text_color='white', text_font_size='8pt', text_align='bottom_right', text_baseline='bottom'),
opts.Path(color='white'),
opts.Spread(width=700),
opts.Overlay(show_legend=False))
### create layout
### z*polys overlays the image and the rectangle plots
### + dmap adds the time plots to the side
### i think the some of the options are redundant
layout = (z*polys + dmap).opts(
opts.GridSpace(shared_xaxis=True, shared_yaxis=True),
opts.Image(cmap='viridis', width=562, height=512),
opts.Labels(text_color='white', text_font_size='8pt', text_align='left', text_baseline='bottom'),
opts.Path(color='white'),
opts.Spread(width=1700),
opts.Curve(width=600, framewise=True),
opts.Polygons(fill_alpha=0.25, line_color='white'),
)
## set the layout to one column so the time plot is underneath
layout.cols(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment