first commit
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
"""
|
||||
Geomedian widget: generates an interactive visualisation of
|
||||
the geomedian summary statistic.
|
||||
"""
|
||||
|
||||
# Load modules
|
||||
import ipywidgets as widgets
|
||||
import matplotlib.pyplot as plt
|
||||
from mpl_toolkits.mplot3d import Axes3D
|
||||
import numpy as np
|
||||
import xarray as xr
|
||||
from odc.algo import xr_geomedian
|
||||
|
||||
def run_app():
|
||||
|
||||
"""
|
||||
An interactive app that allows users to visualise the difference between the median and geomedian time-series summary statistics. By modifying the red-green-blue values of three timesteps for a given pixel, the user changes the output summary statistics.
|
||||
|
||||
This allows a visual representation of the difference through the output values, RGB colour, as well as showing values plotted as a vector on a 3-dimensional space.
|
||||
|
||||
Last modified: December 2021
|
||||
"""
|
||||
|
||||
# Define the red-green-blue sliders for timestep 1
|
||||
p1r = widgets.IntSlider(description='Red', max=255, value=58)
|
||||
p1g = widgets.IntSlider(description='Green', max=255, value=153)
|
||||
p1b = widgets.IntSlider(description='Blue', max=255, value=68)
|
||||
|
||||
# Define the red-green-blue sliders for timestep 2
|
||||
p2r = widgets.IntSlider(description='Red', max=255, value=208)
|
||||
p2g = widgets.IntSlider(description='Green', max=255, value=221)
|
||||
p2b = widgets.IntSlider(description='Blue', max=255, value=203)
|
||||
|
||||
# Define the red-green-blue sliders for timestep 3
|
||||
p3r = widgets.IntSlider(description='Red', max=255, value=202)
|
||||
p3g = widgets.IntSlider(description='Green', max=255, value=82)
|
||||
p3b = widgets.IntSlider(description='Blue', max=255, value=33)
|
||||
|
||||
# Define the median calculation for the timesteps
|
||||
def f(p1r, p1g, p1b, p2r, p2g, p2b, p3r, p3g, p3b):
|
||||
print('Red Median = {}'.format(np.median([p1r, p2r, p3r])))
|
||||
print('Green Median = {}'.format(np.median([p1g, p2g, p3g])))
|
||||
print('Blue Median = {}'.format(np.median([p1b, p2b, p3b])))
|
||||
|
||||
# Define the geomedian calculation for the timesteps
|
||||
def g(p1r, p1g, p1b, p2r, p2g, p2b, p3r, p3g, p3b):
|
||||
print('Red Geomedian = {:.2f}'.format(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).red.values.ravel()[0]))
|
||||
print('Green Geomedian = {:.2f}'.format(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).green.values.ravel()[0]))
|
||||
print('Blue Geomedian = {:.2f}'.format(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).blue.values.ravel()[0]))
|
||||
|
||||
# Define the Timestep 1 box colour
|
||||
def h(p1r, p1g, p1b):
|
||||
fig1, axes1 = plt.subplots(figsize=(2,2))
|
||||
fig1 = plt.imshow([[(p1r, p1g, p1b)]])
|
||||
axes1.set_title('Timestep 1')
|
||||
axes1.axis('off')
|
||||
plt.show(fig1)
|
||||
|
||||
# Define the Timestep 2 box colour
|
||||
def hh(p2r, p2g, p2b):
|
||||
fig2, axes2 = plt.subplots(figsize=(2,2))
|
||||
fig2 = plt.imshow([[(p2r, p2g, p2b)]])
|
||||
axes2.set_title('Timestep 2')
|
||||
axes2.axis('off')
|
||||
plt.show(fig2)
|
||||
|
||||
# Define the Timestep 3 box colour
|
||||
def hhh(p3r, p3g, p3b):
|
||||
fig3, axes3 = plt.subplots(figsize=(2,2))
|
||||
fig3 = plt.imshow([[(p3r, p3g, p3b)]])
|
||||
axes3.set_title('Timestep 3')
|
||||
axes3.axis('off')
|
||||
plt.show(fig3)
|
||||
|
||||
# Define the Median RGB colour box
|
||||
def i(p1r, p1g, p1b, p2r, p2g, p2b, p3r, p3g, p3b):
|
||||
fig4, axes4 = plt.subplots(figsize=(3,3))
|
||||
fig4 = plt.imshow([[(int(np.median([p1r, p2r, p3r])), int(np.median([p1g, p2g, p3g])), int(np.median([p1b, p2b, p3b])))]])
|
||||
axes4.set_title('Median RGB - All timesteps')
|
||||
axes4.axis('off')
|
||||
plt.show(fig4)
|
||||
|
||||
# Define the Geomedian RGB colour box
|
||||
def ii(p1r, p1g, p1b, p2r, p2g, p2b, p3r, p3g, p3b):
|
||||
fig5, axes5 = plt.subplots(figsize=(3,3))
|
||||
fig5 = plt.imshow([[(int(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).red.values.ravel()[0]), int(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).green.values.ravel()[0]), int(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).blue.values.ravel()[0]))]])
|
||||
axes5.set_title('Geomedian RGB - All timesteps')
|
||||
axes5.axis('off')
|
||||
plt.show(fig5)
|
||||
|
||||
# Define 3-D axis to display vectors on
|
||||
def j(p1r, p1g, p1b, p2r, p2g, p2b, p3r, p3g, p3b):
|
||||
fig6 = plt.figure()
|
||||
axes6 = fig6.add_subplot(111, projection='3d')
|
||||
x = [p1r, p2r, p3r, int(np.median([p1r, p2r, p3r])), int(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).red.values.ravel()[0])]
|
||||
y = [p1g, p2g, p3g, int(np.median([p1g, p2g, p3g])), int(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).green.values.ravel()[0])]
|
||||
z = [p1b, p2b, p3b, int(np.median([p1b, p2b, p3b])), int(xr_geomedian(xr.Dataset({"red": (("x", "y", "time"), [[[np.float32(p1r), np.float32(p2r), np.float32(p3r)]]]), "green": (("x", "y", "time"), [[[np.float32(p1g), np.float32(p2g), np.float32(p3g)]]]), "blue": (("x", "y", "time"), [[[np.float32(p1b), np.float32(p2b), np.float32(p3b)]]])})).blue.values.ravel()[0])]
|
||||
labels = [' 1', ' 2', ' 3', ' median', ' geomedian']
|
||||
axes6.scatter(x, y, z, c=['black','black','black','r', 'blue'], marker='o')
|
||||
axes6.set_xlabel('Red')
|
||||
axes6.set_ylabel('Green')
|
||||
axes6.set_zlabel('Blue')
|
||||
axes6.set_xlim3d(0, 255)
|
||||
axes6.set_ylim3d(0, 255)
|
||||
axes6.set_zlim3d(0, 255)
|
||||
for ax, ay, az, label in zip(x, y, z, labels):
|
||||
axes6.text(ax, ay, az, label)
|
||||
plt.title('Each band represents a dimension.')
|
||||
plt.show()
|
||||
|
||||
# Define outputs
|
||||
outf = widgets.interactive_output(f, {'p1r': p1r, 'p2r': p2r,'p3r': p3r, 'p1g': p1g, 'p2g': p2g,'p3g': p3g, 'p1b': p1b, 'p2b': p2b,'p3b': p3b})
|
||||
outg = widgets.interactive_output(g, {'p1r': p1r, 'p2r': p2r,'p3r': p3r, 'p1g': p1g, 'p2g': p2g,'p3g': p3g, 'p1b': p1b, 'p2b': p2b,'p3b': p3b})
|
||||
|
||||
outh = widgets.interactive_output(h, {'p1r': p1r, 'p1g': p1g, 'p1b': p1b})
|
||||
outhh = widgets.interactive_output(hh, {'p2r': p2r, 'p2g': p2g, 'p2b': p2b})
|
||||
outhhh = widgets.interactive_output(hhh, {'p3r': p3r, 'p3g': p3g, 'p3b': p3b})
|
||||
|
||||
outi = widgets.interactive_output(i, {'p1r': p1r, 'p2r': p2r,'p3r': p3r, 'p1g': p1g, 'p2g': p2g,'p3g': p3g, 'p1b': p1b, 'p2b': p2b,'p3b': p3b})
|
||||
outii = widgets.interactive_output(ii, {'p1r': p1r, 'p2r': p2r,'p3r': p3r, 'p1g': p1g, 'p2g': p2g,'p3g': p3g, 'p1b': p1b, 'p2b': p2b,'p3b': p3b})
|
||||
|
||||
outj = widgets.interactive_output(j, {'p1r': p1r, 'p2r': p2r,'p3r': p3r, 'p1g': p1g, 'p2g': p2g,'p3g': p3g, 'p1b': p1b, 'p2b': p2b,'p3b': p3b})
|
||||
|
||||
app_output = widgets.HBox([widgets.VBox([widgets.HBox([outh, widgets.VBox([ p1r, p1g, p1b])]), widgets.HBox([outhh, widgets.VBox([p2r, p2g, p2b])]), widgets.HBox([outhhh, widgets.VBox([ p3r, p3g, p3b])])]), widgets.VBox([widgets.HBox([widgets.VBox([outf, outi]), widgets.VBox([outg, outii])]), outj])])
|
||||
|
||||
return app_output
|
||||
Reference in New Issue
Block a user