import warnings
import numpy as np
from matplotlib.colors import hsv_to_rgb
from lys.errors import NotImplementedWarning
from .CanvasBase import saveCanvas
from .WaveData import WaveData
[docs]class RGBData(WaveData):
"""
Interface to access rgb data in the canvas.
Instance of RGBData is automatically generated by display or append methods.
"""
def __setAppearance(self, key, value):
self._appearance[key] = value
def __getAppearance(self, key, default=None):
return self._appearance.get(key, default)
[docs] @saveCanvas
def setColorRange(self, min='auto', max='auto'):
"""
Set the color range of the image.
Args:
min(float or 'auto'): The minimum value of the range.
max(float or 'auto'): The maximum value of the range.
"""
self.__setAppearance('Range', (min, max))
self._update()
[docs] def getColorRange(self):
"""
Get the color range of the image.
Return:
tuple of length 2: minimum and maximum value of the range.
"""
return self.__getAppearance('Range')
[docs] def getAutoColorRange(self):
"""
Get the automarically-calculated color range of the image, which is used by :meth:`setColorRange` method.
Return:
tuple of length 2: minimum and maximum value of the range.
"""
return (0, np.max(np.abs(self.getWave().data)))
[docs] @saveCanvas
def setColorRotation(self, rot):
"""
Rotate color map of the RGB image if the data is complex.
Args:
rot(float): The rotation.
"""
self.__setAppearance('ColorRotation', rot)
self._update()
[docs] def getColorRotation(self):
"""
Get color rotation of the RGB image.
Return:
float: The rotation.
"""
return self.__getAppearance('ColorRotation')
[docs] @saveCanvas
def setColormapVisible(self, visible):
"""
Set the visibility of the colormap.
Args:
visible(bool): The visibility.
"""
self._setColormapVisible(visible)
self.__setAppearance("colormapVisible", visible)
[docs] def getColormapVisible(self):
"""
Get the visibility of the colormap.
Returns:
bool: The visibility.
"""
return self.__getAppearance('colormapVisible', False)
[docs] @saveCanvas
def setColormapPosition(self, pos):
"""
Set the position of the colormap.
Args:
pos(length 2 sequence): The position of the colormap
"""
self._setColormapPosition(pos)
self.__setAppearance("colormapPosition", pos)
[docs] def getColormapPosition(self):
"""
Get the position of the colormap.
Returns:
length 2 sequence: The position of the colormap.
"""
return self.__getAppearance('colormapPosition', (0, 0))
[docs] @saveCanvas
def setColormapSize(self, size):
"""
Set the size of the colormap.
Args:
size(float): The size of the colormap
"""
self._setColormapSize(size)
self.__setAppearance("colormapSize", size)
[docs] def getColormapSize(self):
"""
Get the size of the colormap.
Returns:
float: The size of the colormap.
"""
return self.__getAppearance('colormapSize', 0.1)
[docs] def getRGBWave(self):
"""
Return RGB wave data that is used to display.
Returns:
Wave: The RGB data.
"""
return self._makeRGBData(self.getFilteredWave(), self.saveAppearance())
[docs] def getColormapData(self, size=50):
x = np.linspace(-1, 1, size)
xy = np.meshgrid(x, x)
res = self._Complex2HSV(xy[0] + xy[1] * 1j, -1, 1, self.getColorRotation())
res[np.sqrt(xy[0]**2 + xy[1]**2) >= 1] = [1, 1, 1]
return res
def _makeRGBData(self, wav, appearance):
wav = wav.duplicate()
if wav.data.ndim == 2:
if 'Range' in appearance:
rmin, rmax = appearance['Range']
if rmin == "auto":
rmin = 0
if rmax == "auto":
rmax = np.max(np.abs(wav.data))
else:
rmin, rmax = 0, np.max(np.abs(wav.data))
wav.data = self._Complex2HSV(wav.data, rmin, rmax, appearance.get('ColorRotation', 0))
elif wav.data.ndim == 3:
if 'Range' in appearance:
rmin, rmax = appearance['Range']
amp = np.where(wav.data < rmin, rmin, wav.data)
amp = np.where(amp > rmax, rmax, amp)
wav.data = (amp - rmin) / (rmax - rmin)
return wav
def _Complex2HSV(self, z, rmin, rmax, hue_start=0):
amp = np.abs(z)
amp = np.where(amp < rmin, rmin, amp)
amp = np.where(amp > rmax, rmax, amp)
ph = np.angle(z, deg=1) + hue_start
h = (ph % 360) / 360
s = np.ones_like(h)
v = (amp - rmin) / (rmax - rmin)
rgb = hsv_to_rgb(np.dstack((h, s, v)))
return rgb
def _loadAppearance(self, appearance):
self.setColorRange(*appearance.get('Range', self.getAutoColorRange()))
self.setColorRotation(appearance.get('ColorRotation', 0))
self.setColormapVisible(appearance.get('colormapVisible', False))
self.setColormapPosition(appearance.get('colormapPosition', (0, 0)))
self.setColormapSize(appearance.get('colormapSize', 0.1))
def _setColormapVisible(self, b):
warnings.warn(str(type(self)) + " does not implement _setColormapVisible(b) method.", NotImplementedWarning)
def _setColormapPosition(self, pos):
warnings.warn(str(type(self)) + " does not implement _setColormapPosition(pos) method.", NotImplementedWarning)
def _setColormapSize(self, size):
warnings.warn(str(type(self)) + " does not implement _setColormapSize(size) method.", NotImplementedWarning)