Aproximadamente el 4.5% de la población mundial es colorblind.
millones de personas en todo el mundo tienen solo un tipo de discapacidad visual. Los números se vuelven significativamente más altos si tuviera que tener en cuenta todas las condiciones. Sin embargo, es un tema raramente discutido.
Como profesional de datos, no desea que nadie malinterprete sus imágenes. Claro, ser más claro es más trabajo, pero hará una parte decente de la población más feliz.
Hoy obtendrá 5 consejos procesables para hacer que sus visualizaciones existentes sean accesibles.
Pautas concretas para implementar la accesibilidad en su visualización de datos
Pero primero, repasemos algunas pautas generales que debe seguir cuando Accesibilidad es una prioridad principal.
Todo lo que se enumera a continuación es una lista de verificación curada y significativamente acortada del Proyecto A11y. Si se pregunta, “A11y” es una abreviatura de “accesibilidad” (11 letras entre “A” y “Y”).
De todos modos, esto es a lo que debes prestar atención:
- No confíe en el color para explicar los datos – Una porción decente de la población es de color ciega o sufre de algún otro discapacidad visual. Los patrones son un camino a seguir.
- Si usa el color, vaya con tonos más oscuros y de alto contraste -Los colores ligeros y de bajo contraste hacen que sea casi imposible distinguir entre grupos en un gráfico visualmente.
- No oculte datos importantes detrás de las interacciones – Los eventos flotantes solo están disponibles en el escritorio. La mayoría de sus usuarios están en teléfonos inteligentes.
- Use etiquetas y leyendas – Sin ellos, el lector no sabe qué representan los datos.
- Traducir los datos en ideas claras – Simplifique los datos tanto como sea posible, y luego algunos. No quieres que nada esté abierto para la interpretación.
- Proporcionar contexto y explicar la visualización – Si es factible, anote los puntos de interés de datos y agregue subtítulo/subtítulos.
- Tener usuarios con lectores de pantalla en mente – Las personas con discapacidades visuales usan lectores de pantalla para navegar por páginas web. Use el texto alternativo para describir sus gráficos incrustados.
Con estos en mente, se me ocurrieron 5 ajustes procesables que puedes hacer a tus visualizaciones en este momento.
Vamos a sumergirnos en el #1.
1. Use una paleta de colores de alto contrast o colorblind
La forma más fácil de entender por qué es importante la elección del color es hacer lo incorrecto primero.
Considere el siguiente conjunto de datos:
x = np.array(["New York", "San Francisco", "Los Angeles", "Chicago", "Miami"])
y1 = np.array([50, 63, 40, 68, 35])
y2 = np.array([77, 85, 62, 89, 58])
y3 = np.array([50, 35, 79, 43, 67])
y4 = np.array([59, 62, 33, 77, 72])
Es un candidato perfecto para una tabla de barras apiladas. En otras palabras, para mostrar las ubicaciones de la oficina en el eje X y los empleados de la pila cuenta con el eje Y.
Ahora imagina que estás realmente en el color verde.
Es posible que desee colorear porciones de barra individuales en diferentes tonos de verde. Es una práctica horrible (a excepción de algunas paletas de colores monocromáticos), como puede ver a partir de lo siguiente:
plt.bar(x, y1, label="HR", color="#32a852")
plt.bar(x, y2, bottom=y1, label="Engineering", color="#3ebd61")
plt.bar(x, y3, bottom=y1 + y2, label="Marketing", color="#2bc254")
plt.bar(x, y4, bottom=y1 + y2 + y3, label="Sales", color="#44c767")
plt.title("[DON'T] Employee Count Per Location And Department", loc="left", fontdict={"weight": "bold"}, y=1.06)
plt.xlabel("Office Location")
plt.ylabel("Count")
plt.legend(loc="upper right", ncol=4)
plt.ylim(top=320)
plt.show()
Muchas personas se preguntan cómo se vería su gráfico si se imprimiera en un libro en blanco y negro.
Este se vería solo marginalmente peor, pero solo porque se ve horrible desde el principio. Distinguir entre porciones de barra es desafiante incluso para las personas sin discapacidades visuales.
Puede usar este sitio web para verificar el contraste entre dos colores.
Arreglo usando una paleta de colores de alto contraste.
Paleta de colores de alto contraste personalizado
Continuaré con la suposición de que te gusta el color verde.
Pregunta: ¿Cómo puedes crear una paleta de colores de alto contraste a partir de un color?
Respuesta: Comience con un tono oscuro y termine con un color lo suficientemente similar a su color principal. En este caso, el oro amarillo es un candidato perfecto.
Obtienes lo mejor de ambos mundos de esta manera. Todavía estás usando los colores que te gustan y los colores no tienen que ser más claros (lo que reduciría el contraste) a medida que pasas por los segmentos de barras.
En la práctica, esto se reduce a jugar con el color Parámetro para todos los segmentos:
plt.bar(x, y1, label="HR", color="#14342B")
plt.bar(x, y2, bottom=y1, label="Engineering", color="#60935D")
plt.bar(x, y3, bottom=y1 + y2, label="Marketing", color="#BAB700")
plt.bar(x, y4, bottom=y1 + y2 + y3, label="Sales", color="#F5E400")
plt.title("[DO] Employee Count Per Location And Department", loc="left", fontdict={"weight": "bold"}, y=1.06)
plt.xlabel("Office Location")
plt.ylabel("Count")
plt.legend(loc="upper right", ncol=4)
plt.ylim(top=320)
plt.show()
Mucho más fácil para los ojos.
Paleta de color colorblind predefinida
Pero considere los siguientes escenarios:
- No tienes tiempo para jugar con diferentes combinaciones de colores
- Tiene tiempo, pero hay alrededor de una docena de categorías en su conjunto de datos (léase: docena de colores para encontrar)
Hay una solución más fácil para facilitar el esquema de color de su gráfico a los ojos al tiempo que se contabiliza a las personas con discapacidades visuales.
Una de esas solución es usar una paleta de colores amigable con el colorblind.
La primera línea del fragmento te muestra cómo:
plt.style.use("tableau-colorblind10")
plt.bar(x, y1, label="HR")
plt.bar(x, y2, bottom=y1, label="Engineering")
plt.bar(x, y3, bottom=y1 + y2, label="Marketing")
plt.bar(x, y4, bottom=y1 + y2 + y3, label="Sales")
plt.title("[DO] Employee Count Per Location And Department", loc="left", fontdict={"weight": "bold"}, y=1.06)
plt.xlabel("Office Location")
plt.ylabel("Count")
plt.legend(loc="upper right", ncol=4)
plt.ylim(top=320)
plt.show()
Esta paleta contiene 10 colores amigables con los colorblind, por lo que es una buena opción para gráficos con 10 grupos o menos.
Si necesita más, tal vez sea mejor repensar su estrategia de visualización.
2. Deje de usar colores: use patrones en su lugar
Otra gran manera de eliminar cualquier tipo de interpretación errónea de sus gráficos es usar patrones en lugar de colores (o como una adición a los colores).
Matplotlib tiene 10 patrones de escotilla puedes elegir.
Puede personalizar aún más las escotillas aumentando su densidad o combinando múltiples patrones. Pero ese es un tema para otro momento.
Para implementar patrones, agregue el hatch parámetro plt.bar(). El ejemplo a continuación elimina el color por completo al establecer fill=False:
plt.bar(x, y1, label="HR", fill=False, hatch="*")
plt.bar(x, y2, bottom=y1, label="Engineering", fill=False, hatch="xx")
plt.bar(x, y3, bottom=y1 + y2, label="Marketing", fill=False, hatch="..")
plt.bar(x, y4, bottom=y1 + y2 + y3, label="Sales", fill=False, hatch="//")
plt.title("[DO] Employee Count Per Location And Department", loc="left", fontdict={"weight": "bold"}, y=1.06)
plt.xlabel("Office Location")
plt.ylabel("Count")
plt.legend(loc="upper right", ncol=4)
plt.ylim(top=320)
plt.show()
Ahora no hay forma de malinterpretar los datos en este gráfico.
¿Puedes mezclar patrones con color?
Si quieres lo mejor de ambos mundos, Color + Pattern es donde está.
Querrá eliminar el parámetro relleno = falso y cambiarlo con color. O simplemente copie el siguiente fragmento de código:
plt.bar(x, y1, label="HR", color="#14342B", hatch="*")
plt.bar(x, y2, bottom=y1, label="Engineering", color="#60935D", hatch="xx")
plt.bar(x, y3, bottom=y1 + y2, label="Marketing", color="#BAB700", hatch="..")
plt.bar(x, y4, bottom=y1 + y2 + y3, label="Sales", color="#F5E400", hatch="//")
plt.title("[DO] Employee Count Per Location And Department", loc="left", fontdict={"weight": "bold"}, y=1.06)
plt.xlabel("Office Location")
plt.ylabel("Count")
plt.legend(loc="upper right", ncol=4)
plt.ylim(top=320)
plt.show()
Los patrones oscuros son claramente visibles en los segmentos de barra, pero ese no siempre es el caso.
El edgecolor El parámetro controla el color del patrón. Veamos qué sucede después de configurarlo en blanco:
plt.bar(x, y1, label="HR", color="#14342B", hatch="*", edgecolor="#FFFFFF")
plt.bar(x, y2, bottom=y1, label="Engineering", color="#60935D", hatch="xx", edgecolor="#FFFFFF")
plt.bar(x, y3, bottom=y1 + y2, label="Marketing", color="#BAB700", hatch="..", edgecolor="#FFFFFF")
plt.bar(x, y4, bottom=y1 + y2 + y3, label="Sales", color="#F5E400", hatch="///", edgecolor="#FFFFFF")
plt.title("[MAYBE] Employee Count Per Location And Department", loc="left", fontdict={"weight": "bold"}, y=1.06)
plt.xlabel("Office Location")
plt.ylabel("Count")
plt.legend(loc="upper right", ncol=4)
plt.ylim(top=320)
plt.show()
El patrón es visible para HORA y Ingeniería Departamentos, pero los dos en la cima son una historia diferente.
Es posible que no tenga problemas para ver las líneas en el segmento de la tabla superior, pero colóquete en el lugar de una persona con discapacidades visuales. Siempre deben ser su marco de referencia.
Recordar: Los patrones de color claro funcionan bien en fondos oscuros. Los patrones de color oscuro funcionan bien en fondos de luz. Ajustar en consecuencia.
3. No abrume el usuario con la información
Este principio va en dos direcciones:
- No ponga demasiada información en una sola tabla
- No ponga demasiados gráficos uno al lado del otro, por ejemplo, en sus aplicaciones/paneles
Hacer ambas simultáneamente es algo así como Pecado final En la visualización de datos.
Comencemos agregando un par de departamentos más a la mezcla.
Los datos se están volviendo difíciles de administrar con Pitón Listas, por lo que he optado por un Pandas DataFrame en su lugar:
import pandas as pd
df = pd.DataFrame({
"HR": [50, 63, 40, 68, 35],
"Engineering": [77, 85, 62, 89, 58],
"Marketing": [50, 35, 79, 43, 67],
"Sales": [59, 62, 33, 77, 72],
"Customer Service": [31, 34, 61, 70, 39],
"Distribution": [35, 21, 66, 90, 31],
"Logistics": [50, 54, 13, 71, 32],
"Production": [22, 51, 54, 28, 40],
"Maintenance": [50, 32, 61, 69, 50],
"Quality Control": [20, 21, 88, 89, 39]
}, index=["New York", "San Francisco", "Los Angeles", "Chicago", "Miami"])
df
Ahora, utilizando la paleta amigable para colorblind, trajemos el recuento de empleados por ubicación y departamento como una tabla de bar apilada. Para hacer las cosas más abarrotadas, también he arrojado recuentos de texto a la mezcla:
plt.style.use("tableau-colorblind10")
ax = df.plot(kind="bar", stacked=True)
for container in ax.containers:
ax.bar_label(container, label_type="center", fontsize=10, color="#000000", fontweight="bold")
plt.title("[DON'T] Employee Count Per Location And Department", loc="left", fontdict={"weight": "bold"}, y=1.06)
plt.xlabel("Office Location")
plt.ylabel("Count")
plt.legend(title="Department", bbox_to_anchor=(1.05, 1), loc='upper left', ncol=1)
plt.show()
Eso es solo feo.
FIJO #1 – Presente menos información
Una forma de resolver este desastre impreventible es mostrar menos información al usuario.
Por ejemplo, solo muestre el recuento de empleados en una ciudad (en todos los departamentos). Entonces puedes agregar un menú desplegable al lado del gráfico para que el usuario pueda controlar la ubicación de la oficina.
El siguiente fragmento de los empleados por departamento en Chicago como un gráfico de barra horizontal:
chicago_data = df.loc["Chicago"].sort_values()
bars = plt.barh(chicago_data.index, chicago_data.values, color="#60935D", edgecolor="#000000")
for bar in bars:
plt.text(bar.get_width() + 2, bar.get_y() + bar.get_height() / 2, f"{int(bar.get_width())}", va="center", ha="left", fontsize=14, color="#000000")
plt.title("[DO] Employee Count by Department in Chicago", loc="left", fontdict={"weight": "bold"}, y=1.06)
plt.xlabel("Count")
plt.ylabel("Department")
plt.show()
FIJO #2 – Reorganizar los datos
Si mostrar menos información no es una opción, tal vez pueda Transponga sus datos.
Por ejemplo, estamos tratando con 5 ubicaciones de oficinas y 10 departamentos. Mostrar 10 columnas en lugar de segmentos de 10 bares es más fácil para los ojos.
De esta manera, terminará mostrando ubicaciones de oficinas como segmentos de barra en lugar de departamentos:
df_transposed = df.T
df_sorted = df_transposed.loc[df_transposed.sum(axis=1).sort_values().index]
ax = df_sorted.plot(kind="barh", width=0.8, edgecolor="#000000", stacked=True)
for container in ax.containers:
ax.bar_label(container, label_type="center", fontsize=10, color="#FFFFFF", fontweight="bold")
plt.title("[DO] Employee Count Per Location And Department", loc="left", fontdict={"weight": "bold"}, y=1.06)
plt.xlabel("Office Location")
plt.ylabel("Count")
plt.show()
Es solo una cuestión de volver a aplicar el problema.
La tabla en Imagen 10 está a millas por delante de la tabla en Imagen 8. Es un hecho. Nadie puede discutir con eso.
4. Proporcione explicaciones en profundidad de los datos en sus gráficos
Puede aprovechar las secciones de subtítulos y/o subtítulos de su gráfico para agregar información adicional.
Esto es útil cuando desea proporcionar más contexto sobre los datos, citar fuentes o resumir los puntos principales de su visualización. El último es más aplicable para personas con discapacidad visual.
El problema con matplotlib es que no tiene una función dedicada para subtítulos y subtítulos de los gráficos. Puedes usar Suptitle (), pero tendrás que jugar con coordenadas del eje X e Y.
Aquí hay un ejemplo:
plt.bar(x, y1, label="HR", color="#14342B", hatch="*")
plt.bar(x, y2, bottom=y1, label="Engineering", color="#60935D", hatch="xx")
plt.bar(x, y3, bottom=y1 + y2, label="Marketing", color="#BAB700", hatch="..")
plt.bar(x, y4, bottom=y1 + y2 + y3, label="Sales", color="#F5E400", hatch="//")
plt.suptitle("Chart shows how the employees are distributed per department and per office location.\nChicago office has the most employees.", x=0.125, y=0.98, ha="left", fontsize=14, fontstyle="italic")
plt.title("Employee Count Per Location And Department", fontsize=20, fontweight="bold", y=1.15, loc="left")
plt.xlabel("Office Location")
plt.ylabel("Count")
plt.legend(loc="upper right", ncol=4)
plt.ylim(top=320)
plt.show()
Si prefiere un subtítulo sobre un subtítulo, solo tiene el cambio de coordenada del eje Y plt.suptitle():
plt.bar(x, y1, label="HR", color="#14342B", hatch="*")
plt.bar(x, y2, bottom=y1, label="Engineering", color="#60935D", hatch="xx")
plt.bar(x, y3, bottom=y1 + y2, label="Marketing", color="#BAB700", hatch="..")
plt.bar(x, y4, bottom=y1 + y2 + y3, label="Sales", color="#F5E400", hatch="//")
plt.suptitle("Chart shows how the employees are distributed per department and per office location.\nChicago office has the most employees.", x=0.125, y=0, ha="left", fontsize=14, fontstyle="italic")
plt.title("Employee Count Per Location And Department", fontsize=20, fontweight="bold", y=1.06, loc="left")
plt.xlabel("Office Location")
plt.ylabel("Count")
plt.legend(loc="upper right", ncol=4)
plt.ylim(top=320)
plt.show()
En general, un subtítulo o una leyenda puede ser el factor decisivo para llevar correctamente su mensaje a una persona con discapacidades visuales.
Simplemente no lo hagas 10 párrafos de largo. De lo contrario, es el tercer punto de este artículo nuevamente.
5. Agregue el texto alternativo al incrustar las parcelas
Muchas personas con discapacidades visuales usan lectores de pantalla.
El problema con los lectores y gráficos de la pantalla es que simplemente no pueden coexistir. Es posible que puedan recoger elementos textuales del gráfico, pero no pueden interpretar el contenido visual. Entonces, cada vez que comparte sus visualizaciones (por ejemplo, incrustarlas en un sitio web), debe agregar texto alternativo.
Este es un párrafo que el lector de pantalla leerá a su usuario.
Para demostrar, usemos el plt.savefig() función para guardar el gráfico como una imagen:
plt.bar(x, y1, label="HR", color="#14342B", hatch="*")
plt.bar(x, y2, bottom=y1, label="Engineering", color="#60935D", hatch="xx")
plt.bar(x, y3, bottom=y1 + y2, label="Marketing", color="#BAB700", hatch="..")
plt.bar(x, y4, bottom=y1 + y2 + y3, label="Sales", color="#F5E400", hatch="//")
plt.suptitle("Chart shows how the employees are distributed per department and per office location.\nChicago office has the most employees.", x=0.125, y=0, ha="left", fontsize=14, fontstyle="italic")
plt.title("Employee Count Per Location And Department", fontsize=20, fontweight='bold', y=1.06, loc="left")
plt.xlabel("Office Location")
plt.ylabel("Count")
plt.legend(loc="upper right", ncol=4)
plt.ylim(top=320)
plt.savefig("figure.jpg", dpi=300, bbox_inches="tight")
En un nuevo documento HTML, agregue un <img> etiqueta eso apunta a la imagen. Aquí es donde debe proporcionar texto alternativo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<img
style="width: 800px;"
src="figure.jpg"
alt="Stacked bar chart. It shows how the employees are distributed per department and per office location. Chicago office has the most employees."
>
</body>
</html>
No puede ver el texto alternativo cuando abre el archivo HTML, pero eso es porque no está usando un lector de pantalla.
Si se detecta el lector de pantalla, el texto alternativo se leerá automáticamente al usuario.
Lo mejor que puedes hacer es usar un complemento de lector de pantalla o apuntar a la imagen que no existe en HTML:
<img
style="width: 800px;"
src="doesnotexist.jpg"
alt="Stacked bar chart. It shows how the employees are distributed per department and per office location. Chicago office has the most employees."
>
Ahora no se puede encontrar la imagen, por lo que se muestra el texto Alt.
Resumiendo la accesibilidad de visualización de datos
Y ahí lo tiene: 5 cosas que siempre debe tener en cuenta al diseñar visualizaciones de datos.
Estos consejos son útiles en general, pero son de vital importancia cuando la accesibilidad es esencial. Y siempre debería ser. Requiere un poco de trabajo extra desde su parte, pero hace que sus hallazgos sean accesibles para millones de personas adicionales en todo el mundo.