Skip to content

Commit

Permalink
moving Image class in the plot_tools_utils module
Browse files Browse the repository at this point in the history
  • Loading branch information
burnout87 committed Jan 24, 2025
1 parent 3d90f3e commit dd60c21
Showing 1 changed file with 220 additions and 4 deletions.
224 changes: 220 additions & 4 deletions oda_api/plot_tools_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,22 @@

__author__ = "Carlo Ferrigno"


from bokeh.layouts import row, gridplot
from bokeh.models import HoverTool
import numpy as np

from astropy import wcs
from bokeh.layouts import row, gridplot, column
from bokeh.models import (CustomJS,
Toggle,
RangeSlider,
HoverTool,
ColorBar,
LinearColorMapper,
LabelSet,
ColumnDataSource,
LogColorMapper)
from bokeh.embed import components
from bokeh.plotting import figure
from bokeh.palettes import Plasma256

# NOTE GW, optional
try:
Expand All @@ -27,7 +38,212 @@

logger = logging.getLogger("oda_api.plot_tools")

__all__ = ['ScatterPlot', 'GridPlot']
__all__ = ['ScatterPlot', 'GridPlot', 'Image']


class Image(object):

def __init__(self, data, header):
self.data = data
self.header = header

def get_html_draw(self,
w=None,
h=None,
catalog=None,
sources_circle_size=15,
x_scale="linear",
y_scale="linear",
x_range=None,
y_range=None,
x0=0,
y0=0,
dw=None,
dh=None,
x_label=None,
y_label=None,
enable_log_cmap=True,
):

msk = ~np.isnan(self.data)

min_v = self.data[msk].min()
max_v = self.data[msk].max()

if x_range is None:
c = self.data.shape[1]
x_range = (0, c)
if y_range is None:
r = self.data.shape[0]
y_range = (0, r)
if dw is None:
dw = x_range[1]
if dh is None:
dh = y_range[1]

fig = figure(plot_width=w,
plot_height=h,
x_axis_type=x_scale,
y_axis_type=y_scale,
x_range=x_range,
y_range=y_range,
x_axis_label=x_label,
y_axis_label=y_label,
tools=['pan,box_zoom,box_select,wheel_zoom,reset,save,crosshair'])

lin_color_mapper = LinearColorMapper(low=min_v, high=max_v, palette='Plasma256')

fig_im = fig.image(image=[self.data], x=x0, y=y0, dw=dw, dh=dh,
color_mapper=lin_color_mapper)

hover = HoverTool(tooltips=[("x", "$x"), ("y", "$y"), ("value", "@image")],
renderers=[fig_im])

fig.add_tools(hover)

if catalog is not None:

lon = catalog.ra
lat = catalog.dec

cur_wcs = wcs.WCS(self.header)

if len(lat) > 0.:
pixcrd = cur_wcs.wcs_world2pix(np.column_stack((lon, lat)), 0)

msk = ~np.isnan(pixcrd[:, 0])
source = ColumnDataSource(data=dict(lon=pixcrd[:, 0][msk] + 0.5,
lat=pixcrd[:, 1][msk] + 0.5,
names=catalog.name[msk]))

fig.scatter(x='lon', y='lat', marker='circle', size=sources_circle_size,
line_color="white", fill_color=None, alpha=1.0, source=source)

labels = LabelSet(x='lon', y='lat', text='names', level='glyph',
x_offset=5, y_offset=5, render_mode='canvas', source=source, text_color='white')

fig.add_layout(labels)

lin_color_bar = ColorBar(color_mapper=lin_color_mapper, label_standoff=12, border_line_color=None,
location=(0, 0), width=15)

fig.add_layout(lin_color_bar, 'right')

graph_slider = RangeSlider(title='Sig. Range', start=min_v, end=max_v, step=(max_v - min_v) / 1000,
value=(min_v, max_v * 0.8))

graph_slider.js_link('value', lin_color_mapper, 'low', attr_selector=0)
graph_slider.js_link('value', lin_color_mapper, 'high', attr_selector=1)

widgets = [graph_slider]

if enable_log_cmap:
log_color_mapper = LogColorMapper(low=max(0, min_v), high=max_v, palette=Plasma256)
graph_slider.js_link('value', log_color_mapper, 'low', attr_selector=0)
graph_slider.js_link('value', log_color_mapper, 'high', attr_selector=1)

log_color_bar = ColorBar(color_mapper=log_color_mapper, label_standoff=2, border_line_color=None,
location=(0, 0), width=15)
fig.add_layout(log_color_bar, 'right')
log_color_bar.visible = False

log_toggle = Toggle(label='Toggle Log. Norm', active=False)
log_toggle.js_on_click(CustomJS(args=dict(lin_color_mapper=lin_color_mapper,
log_color_mapper=log_color_mapper,
fig_im=fig_im,
graph_slider=graph_slider,
min_v=min_v,
lin_color_bar=lin_color_bar,
log_color_bar=log_color_bar),
code="""
if (this.active) {
graph_slider.value = [Math.max(0 + graph_slider.step, graph_slider.value[0]), graph_slider.value[1]];
graph_slider.start = Math.max(0 + graph_slider.step, min_v);
fig_im.glyph.color_mapper = log_color_mapper;
log_color_bar.visible = true;
lin_color_bar.visible = false;
} else {
graph_slider.start = min_v;
fig_im.glyph.color_mapper = lin_color_mapper;
log_color_bar.visible = false;
lin_color_bar.visible = true;
}
"""
)
)
widgets.append(log_toggle)

layout = column(row(widgets),
fig)

script, div = components(layout)

html_dict = {}
html_dict['script'] = script
html_dict['div'] = div
return html_dict

def get_js9_html(self, file_path, region_file=None, js9_id='myJS9'):

file = '''JS9.Preload("product/%s", {scale: 'log', colormap: 'plasma' ''' % file_path
# Region file needs to be loaded using an onload function
if region_file is not None:
file += ''', onload: function(im){ JS9.LoadRegions("product/%s");}}, {display: "%s"});\n''' % \
(region_file, js9_id)
else:
file += '''}, {display: "%s"});''' % js9_id
t = '''
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge;chrome=1" >
<meta name="viewport" content="width=device-width, initial-scale=1">
<link type="image/x-icon" rel="shortcut icon" href="./favicon.ico">
<link type="text/css" rel="stylesheet" href="js9/js9support.css">
<link type="text/css" rel="stylesheet" href="js9/js9.css">
<script type="text/javascript" src="js9/js9prefs.js"></script>
<script type="text/javascript" src="js9/js9support.min.js"></script>
<script type="text/javascript" src="js9/js9.min.js"></script>
<script type="text/javascript" src="js9/js9plugins.js"></script>
</head>
<body>
<center><font size="+1">
</font></center>
<table cellspacing="30">
<tr valign="top">
<td>
</td>
<td>
<tr valign="top">
<td>
<div class="JS9Menubar" id="%sMenubar" ></div>
<div class="JS9Colorbar" id="%sColorbar" ></div>
<div class="JS9" id="%s"></div>
</td>
<td>
<p>
</td>
</tr>
</table>
<script type="text/javascript">
function init(){
var idx, obj;
%s
}
$(document).ready(function(){
init();
});
</script>
</body>
</html>
''' % (js9_id, js9_id, js9_id, file)

return t


class ScatterPlot(object):
Expand Down

0 comments on commit dd60c21

Please sign in to comment.