Add logarithmic color mappers

For #51
This commit is contained in:
usov_i 2023-02-16 17:55:26 +01:00
parent f83aad6b76
commit 3293a74017
3 changed files with 95 additions and 40 deletions

View File

@ -367,16 +367,16 @@ def create():
) )
proj_auto_checkbox.on_click(proj_auto_checkbox_callback) proj_auto_checkbox.on_click(proj_auto_checkbox_callback)
def proj_display_max_spinner_callback(_attr, _old_value, new_value): def proj_display_max_spinner_callback(_attr, _old, new):
color_mapper_proj.high = new_value color_mapper_proj.high = new
proj_display_max_spinner = Spinner( proj_display_max_spinner = Spinner(
value=1, disabled=bool(proj_auto_checkbox.active), mode="int", width=100 value=1, disabled=bool(proj_auto_checkbox.active), mode="int", width=100
) )
proj_display_max_spinner.on_change("value", proj_display_max_spinner_callback) proj_display_max_spinner.on_change("value", proj_display_max_spinner_callback)
def proj_display_min_spinner_callback(_attr, _old_value, new_value): def proj_display_min_spinner_callback(_attr, _old, new):
color_mapper_proj.low = new_value color_mapper_proj.low = new
proj_display_min_spinner = Spinner( proj_display_min_spinner = Spinner(
value=0, disabled=bool(proj_auto_checkbox.active), mode="int", width=100 value=0, disabled=bool(proj_auto_checkbox.active), mode="int", width=100

View File

@ -18,9 +18,11 @@ from bokeh.models import (
HoverTool, HoverTool,
LinearAxis, LinearAxis,
LinearColorMapper, LinearColorMapper,
LogColorMapper,
MultiSelect, MultiSelect,
NumberFormatter, NumberFormatter,
Panel, Panel,
RadioGroup,
Range1d, Range1d,
Select, Select,
Slider, Slider,
@ -483,8 +485,9 @@ def create():
) )
) )
color_mapper = LinearColorMapper() lin_color_mapper = LinearColorMapper(low=0, high=1)
plot.image(source=image_source, color_mapper=color_mapper) log_color_mapper = LogColorMapper(low=0, high=1)
plot_image = plot.image(source=image_source, color_mapper=lin_color_mapper)
plot.image(source=image_source, image="h", global_alpha=0) plot.image(source=image_source, image="h", global_alpha=0)
plot.image(source=image_source, image="k", global_alpha=0) plot.image(source=image_source, image="k", global_alpha=0)
plot.image(source=image_source, image="l", global_alpha=0) plot.image(source=image_source, image="l", global_alpha=0)
@ -573,7 +576,8 @@ def create():
# shared frame ranges # shared frame ranges
frame_range = Range1d(0, 1, bounds=(0, 1)) frame_range = Range1d(0, 1, bounds=(0, 1))
scanning_motor_range = Range1d(0, 1, bounds=(0, 1)) scanning_motor_range = Range1d(0, 1, bounds=(0, 1))
color_mapper_proj = LinearColorMapper() lin_color_mapper_proj = LinearColorMapper(low=0, high=1)
log_color_mapper_proj = LogColorMapper(low=0, high=1)
det_x_range = Range1d(0, IMAGE_W, bounds=(0, IMAGE_W)) det_x_range = Range1d(0, IMAGE_W, bounds=(0, IMAGE_W))
gamma_range = Range1d(0, 1, bounds=(0, 1)) gamma_range = Range1d(0, 1, bounds=(0, 1))
@ -600,7 +604,7 @@ def create():
dict(image=[np.zeros((1, 1), dtype="float32")], x=[0], y=[0], dw=[IMAGE_W], dh=[1]) dict(image=[np.zeros((1, 1), dtype="float32")], x=[0], y=[0], dw=[IMAGE_W], dh=[1])
) )
proj_x_plot.image(source=proj_x_image_source, color_mapper=color_mapper_proj) proj_x_image = proj_x_plot.image(source=proj_x_image_source, color_mapper=lin_color_mapper_proj)
det_y_range = Range1d(0, IMAGE_H, bounds=(0, IMAGE_H)) det_y_range = Range1d(0, IMAGE_H, bounds=(0, IMAGE_H))
nu_range = Range1d(0, 1, bounds=(0, 1)) nu_range = Range1d(0, 1, bounds=(0, 1))
@ -629,7 +633,7 @@ def create():
dict(image=[np.zeros((1, 1), dtype="float32")], x=[0], y=[0], dw=[IMAGE_H], dh=[1]) dict(image=[np.zeros((1, 1), dtype="float32")], x=[0], y=[0], dw=[IMAGE_H], dh=[1])
) )
proj_y_plot.image(source=proj_y_image_source, color_mapper=color_mapper_proj) proj_y_image = proj_y_plot.image(source=proj_y_image_source, color_mapper=lin_color_mapper_proj)
# ROI slice plot # ROI slice plot
roi_avg_plot = figure(plot_height=150, plot_width=IMAGE_PLOT_W, tools="", toolbar_location=None) roi_avg_plot = figure(plot_height=150, plot_width=IMAGE_PLOT_W, tools="", toolbar_location=None)
@ -638,17 +642,41 @@ def create():
roi_avg_plot.line(source=roi_avg_plot_line_source, line_color="steelblue") roi_avg_plot.line(source=roi_avg_plot_line_source, line_color="steelblue")
def colormap_select_callback(_attr, _old, new): def colormap_select_callback(_attr, _old, new):
color_mapper.palette = new lin_color_mapper.palette = new
color_mapper_proj.palette = new log_color_mapper.palette = new
lin_color_mapper_proj.palette = new
log_color_mapper_proj.palette = new
colormap_select = Select( colormap_select = Select(
title="Colormap:", title="Colormap:",
options=[("Greys256", "greys"), ("Plasma256", "plasma"), ("Cividis256", "cividis")], options=[("Greys256", "greys"), ("Plasma256", "plasma"), ("Cividis256", "cividis")],
width=210, width=100,
) )
colormap_select.on_change("value", colormap_select_callback) colormap_select.on_change("value", colormap_select_callback)
colormap_select.value = "Plasma256" colormap_select.value = "Plasma256"
def colormap_scale_rg_callback(selection):
if selection == 0: # Linear
plot_image.glyph.color_mapper = lin_color_mapper
proj_x_image.glyph.color_mapper = lin_color_mapper_proj
proj_y_image.glyph.color_mapper = lin_color_mapper_proj
else: # Logarithmic
if (
display_min_spinner.value > 0
and display_max_spinner.value > 0
and proj_display_min_spinner.value > 0
and proj_display_max_spinner.value > 0
):
plot_image.glyph.color_mapper = log_color_mapper
proj_x_image.glyph.color_mapper = log_color_mapper_proj
proj_y_image.glyph.color_mapper = log_color_mapper_proj
else:
colormap_scale_rg.active = 0
colormap_scale_rg = RadioGroup(labels=["Linear", "Logarithmic"], active=0, width=100)
colormap_scale_rg.on_click(colormap_scale_rg_callback)
def main_auto_checkbox_callback(state): def main_auto_checkbox_callback(state):
if state: if state:
display_min_spinner.disabled = True display_min_spinner.disabled = True
@ -664,20 +692,21 @@ def create():
) )
main_auto_checkbox.on_click(main_auto_checkbox_callback) main_auto_checkbox.on_click(main_auto_checkbox_callback)
def display_max_spinner_callback(_attr, _old_value, new_value): def display_max_spinner_callback(_attr, _old, new):
color_mapper.high = new_value lin_color_mapper.high = new
log_color_mapper.high = new
# TODO: without this _update_image() log color mapper display is delayed
_update_image()
display_max_spinner = Spinner( display_max_spinner = Spinner(value=1, disabled=bool(main_auto_checkbox.active), width=100)
value=1, disabled=bool(main_auto_checkbox.active), mode="int", width=100
)
display_max_spinner.on_change("value", display_max_spinner_callback) display_max_spinner.on_change("value", display_max_spinner_callback)
def display_min_spinner_callback(_attr, _old_value, new_value): def display_min_spinner_callback(_attr, _old, new):
color_mapper.low = new_value lin_color_mapper.low = new
log_color_mapper.low = new
_update_image()
display_min_spinner = Spinner( display_min_spinner = Spinner(value=0, disabled=bool(main_auto_checkbox.active), width=100)
value=0, disabled=bool(main_auto_checkbox.active), mode="int", width=100
)
display_min_spinner.on_change("value", display_min_spinner_callback) display_min_spinner.on_change("value", display_min_spinner_callback)
def proj_auto_checkbox_callback(state): def proj_auto_checkbox_callback(state):
@ -695,20 +724,20 @@ def create():
) )
proj_auto_checkbox.on_click(proj_auto_checkbox_callback) proj_auto_checkbox.on_click(proj_auto_checkbox_callback)
def proj_display_max_spinner_callback(_attr, _old_value, new_value): def proj_display_max_spinner_callback(_attr, _old, new):
color_mapper_proj.high = new_value lin_color_mapper_proj.high = new
log_color_mapper_proj.high = new
_update_proj_plots()
proj_display_max_spinner = Spinner( proj_display_max_spinner = Spinner(value=1, disabled=bool(proj_auto_checkbox.active), width=100)
value=1, disabled=bool(proj_auto_checkbox.active), mode="int", width=100
)
proj_display_max_spinner.on_change("value", proj_display_max_spinner_callback) proj_display_max_spinner.on_change("value", proj_display_max_spinner_callback)
def proj_display_min_spinner_callback(_attr, _old_value, new_value): def proj_display_min_spinner_callback(_attr, _old, new):
color_mapper_proj.low = new_value lin_color_mapper_proj.low = new
log_color_mapper_proj.low = new
_update_proj_plots()
proj_display_min_spinner = Spinner( proj_display_min_spinner = Spinner(value=0, disabled=bool(proj_auto_checkbox.active), width=100)
value=0, disabled=bool(proj_auto_checkbox.active), mode="int", width=100
)
proj_display_min_spinner.on_change("value", proj_display_min_spinner_callback) proj_display_min_spinner.on_change("value", proj_display_min_spinner_callback)
events_data = dict( events_data = dict(
@ -881,7 +910,7 @@ def create():
layout_image = column(gridplot([[proj_v, None], [plot, proj_h]], merge_tools=False)) layout_image = column(gridplot([[proj_v, None], [plot, proj_h]], merge_tools=False))
colormap_layout = column( colormap_layout = column(
colormap_select, row(colormap_select, column(Spacer(height=15), colormap_scale_rg)),
main_auto_checkbox, main_auto_checkbox,
row(display_min_spinner, display_max_spinner), row(display_min_spinner, display_max_spinner),
proj_auto_checkbox, proj_auto_checkbox,

View File

@ -13,8 +13,10 @@ from bokeh.models import (
Div, Div,
FileInput, FileInput,
LinearColorMapper, LinearColorMapper,
LogColorMapper,
NumericInput, NumericInput,
Panel, Panel,
RadioGroup,
Select, Select,
Spacer, Spacer,
Spinner, Spinner,
@ -254,11 +256,15 @@ def create():
) )
plot.toolbar.logo = None plot.toolbar.logo = None
color_mapper = LinearColorMapper(nan_color=(0, 0, 0, 0), low=0, high=1) lin_color_mapper = LinearColorMapper(nan_color=(0, 0, 0, 0), low=0, high=1)
log_color_mapper = LogColorMapper(nan_color=(0, 0, 0, 0), low=0, high=1)
image_source = ColumnDataSource(dict(image=[np.zeros((1, 1))], x=[0], y=[0], dw=[1], dh=[1])) image_source = ColumnDataSource(dict(image=[np.zeros((1, 1))], x=[0], y=[0], dw=[1], dh=[1]))
plot.image(source=image_source, color_mapper=color_mapper) plot_image = plot.image(source=image_source, color_mapper=lin_color_mapper)
plot.add_layout(ColorBar(color_mapper=color_mapper, width=15), "right") lin_color_bar = ColorBar(color_mapper=lin_color_mapper, width=15)
log_color_bar = ColorBar(color_mapper=log_color_mapper, width=15, visible=False)
plot.add_layout(lin_color_bar, "right")
plot.add_layout(log_color_bar, "right")
scatter_source = ColumnDataSource(dict(x=[], y=[])) scatter_source = ColumnDataSource(dict(x=[], y=[]))
plot.scatter(source=scatter_source, size=4, fill_color="green", line_color="green") plot.scatter(source=scatter_source, size=4, fill_color="green", line_color="green")
@ -298,7 +304,8 @@ def create():
redef_ub_ti = TextInput(width=490, disabled=True) redef_ub_ti = TextInput(width=490, disabled=True)
def colormap_select_callback(_attr, _old, new): def colormap_select_callback(_attr, _old, new):
color_mapper.palette = new lin_color_mapper.palette = new
log_color_mapper.palette = new
colormap_select = Select( colormap_select = Select(
title="Colormap:", title="Colormap:",
@ -309,17 +316,36 @@ def create():
colormap_select.value = "Plasma256" colormap_select.value = "Plasma256"
def display_min_ni_callback(_attr, _old, new): def display_min_ni_callback(_attr, _old, new):
color_mapper.low = new lin_color_mapper.low = new
log_color_mapper.low = new
display_min_ni = NumericInput(title="Intensity min:", value=0, mode="float", width=70) display_min_ni = NumericInput(title="Intensity min:", value=0, mode="float", width=70)
display_min_ni.on_change("value", display_min_ni_callback) display_min_ni.on_change("value", display_min_ni_callback)
def display_max_ni_callback(_attr, _old, new): def display_max_ni_callback(_attr, _old, new):
color_mapper.high = new lin_color_mapper.high = new
log_color_mapper.high = new
display_max_ni = NumericInput(title="max:", value=1, mode="float", width=70) display_max_ni = NumericInput(title="max:", value=1, mode="float", width=70)
display_max_ni.on_change("value", display_max_ni_callback) display_max_ni.on_change("value", display_max_ni_callback)
def colormap_scale_rg_callback(selection):
if selection == 0: # Linear
plot_image.glyph.color_mapper = lin_color_mapper
lin_color_bar.visible = True
log_color_bar.visible = False
else: # Logarithmic
if display_min_ni.value > 0 and display_max_ni.value > 0:
plot_image.glyph.color_mapper = log_color_mapper
lin_color_bar.visible = False
log_color_bar.visible = True
else:
colormap_scale_rg.active = 0
colormap_scale_rg = RadioGroup(labels=["Linear", "Logarithmic"], active=0, width=100)
colormap_scale_rg.on_click(colormap_scale_rg_callback)
xrange_min_ni = NumericInput(title="x range min:", value=0, mode="float", width=70) xrange_min_ni = NumericInput(title="x range min:", value=0, mode="float", width=70)
xrange_max_ni = NumericInput(title="max:", value=1, mode="float", width=70) xrange_max_ni = NumericInput(title="max:", value=1, mode="float", width=70)
xrange_step_ni = NumericInput(title="x mesh:", value=0.01, mode="float", width=70) xrange_step_ni = NumericInput(title="x mesh:", value=0.01, mode="float", width=70)
@ -355,7 +381,7 @@ def create():
hkl_div, hkl_div,
row(hkl_normal, hkl_cut, hkl_delta), row(hkl_normal, hkl_cut, hkl_delta),
row(hkl_in_plane_x, hkl_in_plane_y), row(hkl_in_plane_x, hkl_in_plane_y),
colormap_select, row(colormap_select, column(Spacer(height=15), colormap_scale_rg)),
row(display_min_ni, display_max_ni), row(display_min_ni, display_max_ni),
row(column(Spacer(height=19), auto_range_cb)), row(column(Spacer(height=19), auto_range_cb)),
row(xrange_min_ni, xrange_max_ni), row(xrange_min_ni, xrange_max_ni),