Skip to content

Commit

Permalink
hold sync when update hist
Browse files Browse the repository at this point in the history
and add concept notebook with possible colorbar implementations

[ci skip] [rtd skip]
  • Loading branch information
pllim committed Oct 17, 2023
1 parent 01fa1ea commit 9fc2c03
Show file tree
Hide file tree
Showing 2 changed files with 289 additions and 7 deletions.
17 changes: 10 additions & 7 deletions jdaviz/configs/default/plugins/plot_options/plot_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from astropy.visualization import (
ManualInterval, ContrastBiasStretch, PercentileInterval
)
from echo import delay_callback
from traitlets import Any, Dict, Float, Bool, Int, List, Unicode, observe

from glue.core.subset_group import GroupedSubset
Expand Down Expand Up @@ -411,11 +412,12 @@ def state_attr_for_line_visible(state):

self.stretch_histogram.add_line('vmin', x=[0, 0], y=[0, 1], ynorm=True, color='#c75d2c')
self.stretch_histogram.add_line('vmax', x=[0, 0], y=[0, 1], ynorm=True, color='#c75d2c')
self.stretch_histogram.figure.axes[0].label = 'pixel value'
self.stretch_histogram.figure.axes[0].num_ticks = 3
self.stretch_histogram.figure.axes[0].tick_format = '0.1e'
self.stretch_histogram.figure.axes[1].label = 'density'
self.stretch_histogram.figure.axes[1].num_ticks = 2
with self.stretch_histogram.figure.hold_sync():
self.stretch_histogram.figure.axes[0].label = 'pixel value'
self.stretch_histogram.figure.axes[0].num_ticks = 3
self.stretch_histogram.figure.axes[0].tick_format = '0.1e'
self.stretch_histogram.figure.axes[1].label = 'density'
self.stretch_histogram.figure.axes[1].num_ticks = 2
self.stretch_histogram_widget = f'IPY_MODEL_{self.stretch_histogram.model_id}'

self.subset_visible = PlotOptionsSyncState(self, self.viewer, self.layer, 'visible',
Expand Down Expand Up @@ -650,8 +652,9 @@ def _update_stretch_histogram(self, msg={}):
stretch_vstep = (hist_lims[1] - hist_lims[0]) / 100.
self.stretch_vstep = np.round(stretch_vstep, decimals=-int(np.log10(stretch_vstep))+1) # noqa

self.stretch_histogram.viewer.state.hist_x_min = hist_lims[0]
self.stretch_histogram.viewer.state.hist_x_max = hist_lims[1]
with delay_callback(self.stretch_histogram.viewer.state, 'hist_x_min', 'hist_x_max'):
self.stretch_histogram.viewer.state.hist_x_min = hist_lims[0]
self.stretch_histogram.viewer.state.hist_x_max = hist_lims[1]

self.stretch_histogram.figure.title = f"{len(sub_data)} pixels"

Expand Down
279 changes: 279 additions & 0 deletions notebooks/concepts/imviz_colorbar_mpl.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "7b9bf568-7416-46ad-9108-0d1d97c9af32",
"metadata": {},
"source": [
"Concept notebook to explore colorbar implementation in bqplot vs Matplotlib.\n",
"\n",
"Matplotlib example is from https://docs.astropy.org/en/latest/visualization/normalization.html ."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c6374a84-beaa-4e98-ae25-75ece45cc54b",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"%matplotlib inline"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4f4c35a6-ba8f-4f63-b68a-607de30c08f9",
"metadata": {},
"outputs": [],
"source": [
"# Generate a test image\n",
"image = np.arange(65536).reshape((256, 256))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9c6f2384-b70b-4106-973d-b62623d67e5f",
"metadata": {},
"outputs": [],
"source": [
"from astropy.visualization import simple_norm\n",
"\n",
"# Create an ImageNormalize object\n",
"norm = simple_norm(image, 'sqrt')\n",
"\n",
"# Display the image\n",
"fig, ax = plt.subplots()\n",
"im = ax.imshow(image, origin='lower', norm=norm)\n",
"fig.colorbar(im, location=\"bottom\")"
]
},
{
"cell_type": "markdown",
"id": "5ab7bbf6-372b-4aa0-9f02-a5dacace164e",
"metadata": {},
"source": [
"How, how does Imviz fare?"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3b04c9b4-ddf4-4025-aea2-77d5920e53dd",
"metadata": {},
"outputs": [],
"source": [
"from jdaviz import Imviz"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e9349094-620b-40c4-8ae2-d424b5983119",
"metadata": {},
"outputs": [],
"source": [
"imviz = Imviz()\n",
"imviz.load_data(image, data_label=\"test image\")\n",
"imviz.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "27a06c70-b7af-4055-9b50-2d1269ba38d3",
"metadata": {},
"outputs": [],
"source": [
"plg = imviz.plugins[\"Plot Options\"]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8e261197-8db5-4051-9f9f-07e7245cc53d",
"metadata": {},
"outputs": [],
"source": [
"plg.open_in_tray()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ed2c2107-1803-4481-81b9-e6ab162e7425",
"metadata": {},
"outputs": [],
"source": [
"# Colormap (to compare with Matplotlib above)\n",
"plg.image_colormap = \"Viridis\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cc2331cf-e8e4-4ad9-ac80-3dac338c298a",
"metadata": {},
"outputs": [],
"source": [
"# Monochromatic\n",
"plg.image_color_mode = \"Monochromatic\"\n",
"plg.image_color = \"red\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "52dd988b-a763-4caa-acee-3d39682bdcce",
"metadata": {},
"outputs": [],
"source": [
"plg.stretch_function = \"Square Root\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "83167260-2cc8-4e33-9fd0-9105db23d521",
"metadata": {},
"outputs": [],
"source": [
"imviz.default_viewer.zoom_level = \"fit\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0e2e02e3-7a25-47c1-a6db-b5ccafcc823d",
"metadata": {},
"outputs": [],
"source": [
"from astropy.visualization import ManualInterval, ContrastBiasStretch\n",
"from glue.config import colormaps, stretches\n",
"from glue.viewers.image.composite_array import COLOR_CONVERTER\n",
"\n",
"# Copied from glue/viewers/image/composite_array.py\n",
"\n",
"color_mode = plg._obj.image_color_mode_value\n",
"interval = ManualInterval(vmin=plg._obj.stretch_vmin_value, vmax=plg._obj.stretch_vmax_value)\n",
"contrast_bias = ContrastBiasStretch(plg._obj.image_contrast_value, plg._obj.image_bias_value)\n",
"stretch = stretches.members[plg._obj.stretch_function_value]\n",
"array = plg._obj.stretch_histogram.figure.marks[0].x\n",
"\n",
"data = interval(array)\n",
"data = contrast_bias(data, out=data)\n",
"data = stretch(data, out=data)\n",
"\n",
"if color_mode == 'Colormaps':\n",
" cmap = colormaps[plg._obj.image_colormap.text]\n",
" if hasattr(cmap, \"get_bad\"):\n",
" bad_color = cmap.get_bad().tolist()[:3]\n",
" layer_cmap = cmap.with_extremes(bad=bad_color + [plg._obj.image_opacity_value])\n",
" else:\n",
" layer_cmap = cmap\n",
"\n",
" # Compute colormapped image\n",
" plane = layer_cmap(data)\n",
"\n",
"else: # Monochromatic\n",
" # Get color\n",
" color = COLOR_CONVERTER.to_rgba_array(plg._obj.image_color_value)[0]\n",
" plane = data[:, np.newaxis] * color\n",
" plane[:, 3] = 1\n",
"\n",
"plane = np.clip(plane, 0, 1, out=plane)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "25389f05-caf9-4975-b83b-ed4881f4b307",
"metadata": {},
"outputs": [],
"source": [
"import matplotlib\n",
"\n",
"ipycolors = [matplotlib.colors.rgb2hex(p, keep_alpha=False) for p in plane]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2ef6b087-04af-4f91-8bc5-bd0c50f2601a",
"metadata": {},
"outputs": [],
"source": [
"# This draws dots across the histogram. Drawing line does not work. ynorm=True does not put it on top.\n",
"#x = plg._obj.stretch_histogram.figure.marks[0].x\n",
"#plg._obj.stretch_histogram.add_scatter('colorbar', x=x, y=np.ones(x.size), ynorm=True, color=ipycolors)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "637b0051-b1d1-4018-9bb6-e502dc9ebcb5",
"metadata": {},
"outputs": [],
"source": [
"# This encodes colorbar inside histogram bars\n",
"plg._obj.stretch_histogram.figure.marks[1].colors = ipycolors"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b6b38132-8241-4c7e-876c-9e02cc97cfc6",
"metadata": {},
"outputs": [],
"source": [
"# Re-displays the histogram\n",
"plg._obj.stretch_histogram"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "09810929-c901-45c4-9595-34b322a8de50",
"metadata": {},
"outputs": [],
"source": [
"# Matplotlib rendering of the same colors, as reassurance\n",
"x = plg._obj.stretch_histogram.figure.marks[0].x\n",
"plt.scatter(x, np.ones(x.size), color=ipycolors)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b6fc89f6-801c-4944-945e-73c475b5fd72",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

0 comments on commit 9fc2c03

Please sign in to comment.