Einführung
Matplotlib ist eine beliebte Datenvisualisierungsbibliothek in Python. Es hat verschiedene integrierte Funktionen, darunter die Möglichkeit, Farbsehensstörungen zu simulieren. In diesem Lab werden Sie durch die Schritte geführt, um Matplotlib zu verwenden, um Farbsehensstörungen zu simulieren.
Tipps für die VM
Nachdem der VM-Start abgeschlossen ist, klicken Sie in der oberen linken Ecke, um zur Registerkarte Notebook zu wechseln und Jupyter Notebook für die Übung zu nutzen.
Manchmal müssen Sie einige Sekunden warten, bis Jupyter Notebook fertig geladen ist. Die Validierung von Vorgängen kann aufgrund von Einschränkungen in Jupyter Notebook nicht automatisiert werden.
Wenn Sie bei der Lernphase Probleme haben, können Sie Labby gerne fragen. Geben Sie nach der Sitzung Feedback, und wir werden das Problem für Sie prompt beheben.
Importieren der erforderlichen Bibliotheken und Module
Zunächst müssen wir die erforderlichen Bibliotheken und Module importieren, einschließlich Matplotlib, NumPy und colorspacious. Wir legen auch die Farbfilteroptionen fest, die wir simulieren möchten.
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",
}
Definieren der Farbfilterfunktion
Als nächstes definieren wir eine Funktion, die eine Farbfilterfunktion basierend auf dem Namen des Farbfilters erstellt. Diese Funktion verwendet das colorspacious-Modul, um das Eingabebild in einen anderen Farbraum basierend auf dem Namen des Farbfilters umzuwandeln.
def _get_color_filter(name):
"""
Gegeben einen Namen für einen Farbfilter, erstellt eine Farbfilterfunktion.
Parameter
----------
name : str
Der Name des Farbfilters, einer der folgenden:
- ``"none"``:...
- ``"greyscale"``: Konvertiert die Eingabe in Helligkeit.
- ``"deuteranopia"``: Simuliert die häufigste Form von Rot-Grün-Farbenblindheit.
- ``"protanopia"``: Simuliert eine seltnere Form von Rot-Grün-Farbenblindheit.
- ``"tritanopia"``: Simuliert die seltene Form von Blau-Gelb-Farbenblindheit.
Farbkonvertierungen verwenden `colorspacious`_.
Rückgabe
-------
callable
Eine Farbfilterfunktion der Form:
def filter(input: np.ndarray[M, N, D])-> np.ndarray[M, N, D]
wobei (M, N) die Bilddimensionen sind und D die Farbtiefe (3 für RGB, 4 für RGBA). Alpha wird unverändert weitergeleitet und sonst ignoriert.
"""
if name not in _MENU_ENTRIES:
raise ValueError(f"Unsupported filter name: {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
Menüeintrag festlegen
Wir definieren eine Funktion, die den Menüeintrag basierend auf dem ausgewählten Namen des Farbfilters festlegt. Diese Funktion aktualisiert die Farbfilterfunktion basierend auf der Auswahl.
def _set_menu_entry(tb, name):
tb.canvas.figure.set_agg_filter(_get_color_filter(name))
tb.canvas.draw_idle()
Werkzeugleiste einrichten
Als nächstes definieren wir eine Funktion, die die Werkzeugleiste basierend auf dem verwendeten Backendtyp einrichtet. Diese Funktion erstellt einen Button, der dem Benutzer ermöglicht, den Typ des Farbfilters auszuwählen, den er simulieren möchte.
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")
Beispielbilder erstellen
Wir erstellen Beispielbilder, um die Farbfilterfunktion zu demonstrieren. Wir importieren ein Beispielbild von Grace Hopper und plotten es mit Matplotlib. Wir erstellen auch einen Plot von Sinuswellen.
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()
Zusammenfassung
In diesem Lab haben wir gelernt, wie man mit Matplotlib Farbsehdysfunktionen simulieren kann. Wir haben das colorspacious-Modul verwendet, um das Eingabebild in einen anderen Farbraum basierend auf dem ausgewählten Namen des Farbfilters umzuwandeln. Wir haben auch Beispielbilder erstellt, um die Farbfilterfunktion zu demonstrieren.