Introducción
Matplotlib es una popular biblioteca de visualización de datos en Python. Tiene varias características integradas, incluyendo la capacidad de simular deficiencias en la visión del color. Esta práctica te guiará a través de los pasos para utilizar Matplotlib para simular deficiencias en la visión del color.
Consejos sobre la VM
Una vez finalizada la inicialización de la VM, haz clic en la esquina superior izquierda para cambiar a la pestaña Cuaderno y acceder a Jupyter Notebook para practicar.
A veces, es posible que tengas que esperar unos segundos a que Jupyter Notebook termine de cargarse. La validación de las operaciones no se puede automatizar debido a las limitaciones de Jupyter Notebook.
Si tienes problemas durante el aprendizaje, no dudes en preguntar a Labby. Proporciona retroalimentación después de la sesión y resolveremos rápidamente el problema para ti.
Importar las bibliotecas y módulos necesarios
En primer lugar, necesitamos importar las bibliotecas y módulos necesarios, incluyendo Matplotlib, NumPy y colorspacious. También establecemos las opciones de filtro de color que queremos simular.
import functools
from pathlib import Path
import colorspacious
import numpy as np
_BUTTON_NAME = "Filter"
_BUTTON_HELP = "Simulate color vision deficiencies"
_MENU_ENTRIES = {
"None": None,
"Greyscale": "greyscale",
"Deuteranopia": "deuteranomaly",
"Protanopia": "protanomaly",
"Tritanopia": "tritanomaly",
}
Definir la función de filtro de color
A continuación, definimos una función que crea una función de filtro de color basada en el nombre del filtro de color. Esta función utiliza el módulo colorspacious para convertir la imagen de entrada a un espacio de color diferente según el nombre del filtro de color.
def _get_color_filter(name):
"""
Dado el nombre de un filtro de color, crea una función de filtro de color.
Parámetros
----------
name : str
El nombre del filtro de color, uno de los siguientes:
- ``"none"``:...
- ``"greyscale"``: Convertir la entrada a luminosidad.
- ``"deuteranopia"``: Simular la forma más común de daltonismo de rojo-verde.
- ``"protanopia"``: Simular una forma menos común de daltonismo de rojo-verde.
- ``"tritanopia"``: Simular la forma rara de daltonismo azul-amarillo.
Las conversiones de color utilizan `colorspacious`_.
Devuelve
-------
callable
Una función de filtro de color que tiene la forma:
def filter(input: np.ndarray[M, N, D])-> np.ndarray[M, N, D]
donde (M, N) son las dimensiones de la imagen y D es la profundidad de color (3 para RGB, 4 para RGBA). El canal alfa se pasa sin cambios y en caso contrario se ignora.
"""
if name not in _MENU_ENTRIES:
raise ValueError(f"Nombre de filtro no admitido: {name!r}")
name = _MENU_ENTRIES[name]
if name is None:
return None
elif name == "greyscale":
rgb_to_jch = colorspacious.cspace_converter("sRGB1", "JCh")
jch_to_rgb = colorspacious.cspace_converter("JCh", "sRGB1")
def convert(im):
greyscale_JCh = rgb_to_jch(im)
greyscale_JCh[..., 1] = 0
im = jch_to_rgb(greyscale_JCh)
return im
else:
cvd_space = {"name": "sRGB1+CVD", "cvd_type": name, "severity": 100}
convert = colorspacious.cspace_converter(cvd_space, "sRGB1")
def filter_func(im, dpi):
alpha = None
if im.shape[-1] == 4:
im, alpha = im[..., :3], im[..., 3]
im = convert(im)
if alpha is not None:
im = np.dstack((im, alpha))
return np.clip(im, 0, 1), 0, 0
return filter_func
Establecer la entrada del menú
Definimos una función que establece la entrada del menú basada en el nombre del filtro de color seleccionado. Esta función actualiza la función de filtro de color según la selección.
def _set_menu_entry(tb, name):
tb.canvas.figure.set_agg_filter(_get_color_filter(name))
tb.canvas.draw_idle()
Configurar la barra de herramientas
A continuación, definimos una función que configura la barra de herramientas según el tipo de backend utilizado. Esta función crea un botón que permite al usuario seleccionar el tipo de filtro de color que se desea simular.
def setup(figure):
tb = figure.canvas.toolbar
if tb is None:
return
for cls in type(tb).__mro__:
pkg = cls.__module__.split(".")[0]
if pkg!= "matplotlib":
break
if pkg == "gi":
_setup_gtk(tb)
elif pkg in ("PyQt5", "PySide2", "PyQt6", "PySide6"):
_setup_qt(tb)
elif pkg == "tkinter":
_setup_tk(tb)
elif pkg == "wx":
_setup_wx(tb)
else:
raise NotImplementedError("The current backend is not supported")
Crear imágenes de muestra
Creamos imágenes de muestra para demostrar la función de filtro de color. Importamos una imagen de muestra de Grace Hopper y la representamos utilizando Matplotlib. También creamos una gráfica de ondas sinusoidales.
if __name__ == '__main__':
import matplotlib.pyplot as plt
from matplotlib import cbook
plt.rcParams['figure.hooks'].append('mplcvd:setup')
fig, axd = plt.subplot_mosaic(
[
['viridis', 'turbo'],
['photo', 'lines']
]
)
delta = 0.025
x = y = np.arange(-3.0, 3.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (Z1 - Z2) * 2
imv = axd['viridis'].imshow(
Z, interpolation='bilinear',
origin='lower', extent=[-3, 3, -3, 3],
vmax=abs(Z).max(), vmin=-abs(Z).max()
)
fig.colorbar(imv)
imt = axd['turbo'].imshow(
Z, interpolation='bilinear', cmap='turbo',
origin='lower', extent=[-3, 3, -3, 3],
vmax=abs(Z).max(), vmin=-abs(Z).max()
)
fig.colorbar(imt)
## A sample image
with cbook.get_sample_data('grace_hopper.jpg') as image_file:
photo = plt.imread(image_file)
axd['photo'].imshow(photo)
th = np.linspace(0, 2*np.pi, 1024)
for j in [1, 2, 4, 6]:
axd['lines'].plot(th, np.sin(th * j), label=f'$\\omega={j}$')
axd['lines'].legend(ncols=2, loc='upper right')
plt.show()
Resumen
En este laboratorio, aprendimos cómo simular deficiencias en la visión del color utilizando Matplotlib. Utilizamos el módulo colorspacious para convertir la imagen de entrada a un espacio de color diferente según el nombre del filtro de color seleccionado. También creamos imágenes de muestra para demostrar la función de filtro de color.