Usando matplotlib en Python, estoy trazando entre 20 y 50 líneas. Usando las escalas de colores deslizantes de matplotlib, estos se vuelven indistinguibles después de trazar un cierto número de líneas (mucho antes de 20).
Si bien he visto algunos ejemplos de código en Matlab y C# para crear mapas de colores de un número arbitrario de colores que se distinguen al máximo entre sí, no puedo encontrar nada para Python.
¿Alguien puede señalarme la dirección de algo en Python que hará esto?
Salud
Me encantó la idea de la paleta creada por @xuancong84 y modifiqué un poco su código para que no dependiera del canal alfa. Lo dejo aquí para que otros lo usen, ¡gracias @xuancong84!
import math import numpy as np from matplotlib.colors import ListedColormap from matplotlib.cm import hsv def generate_colormap(number_of_distinct_colors: int = 80): if number_of_distinct_colors == 0: number_of_distinct_colors = 80 number_of_shades = 7 number_of_distinct_colors_with_multiply_of_shades = int(math.ceil(number_of_distinct_colors / number_of_shades) * number_of_shades) # Create an array with uniformly drawn floats taken from <0, 1) partition linearly_distributed_nums = np.arange(number_of_distinct_colors_with_multiply_of_shades) / number_of_distinct_colors_with_multiply_of_shades # We are going to reorganise monotonically growing numbers in such way that there will be single array with saw-like pattern # but each saw tooth is slightly higher than the one before # First divide linearly_distributed_nums into number_of_shades sub-arrays containing linearly distributed numbers arr_by_shade_rows = linearly_distributed_nums.reshape(number_of_shades, number_of_distinct_colors_with_multiply_of_shades // number_of_shades) # Transpose the above matrix (columns become rows) - as a result each row contains saw tooth with values slightly higher than row above arr_by_shade_columns = arr_by_shade_rows.T # Keep number of saw teeth for later number_of_partitions = arr_by_shade_columns.shape[0] # Flatten the above matrix - join each row into single array nums_distributed_like_rising_saw = arr_by_shade_columns.reshape(-1) # HSV colour map is cyclic (https://matplotlib.org/tutorials/colors/colormaps.html#cyclic), we'll use this property initial_cm = hsv(nums_distributed_like_rising_saw) lower_partitions_half = number_of_partitions // 2 upper_partitions_half = number_of_partitions - lower_partitions_half # Modify lower half in such way that colours towards beginning of partition are darker # First colours are affected more, colours closer to the middle are affected less lower_half = lower_partitions_half * number_of_shades for i in range(3): initial_cm[0:lower_half, i] *= np.arange(0.2, 1, 0.8/lower_half) # Modify second half in such way that colours towards end of partition are less intense and brighter # Colours closer to the middle are affected less, colours closer to the end are affected more for i in range(3): for j in range(upper_partitions_half): modifier = np.ones(number_of_shades) - initial_cm[lower_half + j * number_of_shades: lower_half + (j + 1) * number_of_shades, i] modifier = j * modifier / upper_partitions_half initial_cm[lower_half + j * number_of_shades: lower_half + (j + 1) * number_of_shades, i] += modifier return ListedColormap(initial_cm)
Estos son los colores que tengo:
from matplotlib import pyplot as plt import numpy as np N = 16 M = 7 H = np.arange(N*M).reshape([N,M]) fig = plt.figure(figsize=(10, 10)) ax = plt.pcolor(H, cmap=generate_colormap(N*M)) plt.show()
Recientemente, también me encontré con el mismo problema. Así que creé el siguiente código Python simple para generar colores distinguibles visualmente para jupyter notebook matplotlib. No se distingue perceptivamente al máximo, pero funciona mejor que la mayoría de los mapas de colores integrados en matplotlib.
El algoritmo divide la escala HSV en 2 partes, la primera parte con un valor RGB creciente, la segunda parte con alfa decreciente para que el color se mezcle con el fondo blanco.
Tenga en cuenta que si está utilizando cualquier kit de herramientas que no sea jupyter notebook, debe asegurarse de que el fondo sea blanco; de lo contrario, la combinación alfa será diferente y el color resultante también será diferente.
Además, el carácter distintivo del color depende en gran medida de la pantalla de su computadora, proyector, etc. Una paleta de colores distinguible en una pantalla no implica necesariamente en otra. Debe probarlo físicamente si desea usarlo para la presentación.
import numpy as np import matplotlib.pyplot as plt from matplotlib.colors import ListedColormap def generate_colormap(N): arr = np.arange(N)/N N_up = int(math.ceil(N/7)*7) arr.resize(N_up) arr = arr.reshape(7,N_up//7).T.reshape(-1) ret = matplotlib.cm.hsv(arr) n = ret[:,3].size a = n//2 b = na for i in range(3): ret[0:n//2,i] *= np.arange(0.2,1,0.8/a) ret[n//2:,3] *= np.arange(1,0.1,-0.9/b) # print(ret) return ret N = 16 H = np.arange(N*N).reshape([N,N]) fig = plt.figure(figsize=(10, 10)) ax = plt.pcolor(H, cmap=ListedColormap(generate_colormap(N*N)))