Jak wybrać nowy kolor dla każdej kreślonej linii w figurze w matplotlib?

109

Chciałbym NIE określać koloru dla każdej kreślonej linii i aby każda linia miała inny kolor. Ale jeśli biegnę:

from matplotlib import pyplot as plt
for i in range(20):
    plt.plot([0, 1], [i, i])

plt.show()

wtedy otrzymuję ten wynik:

Obraz wyjściowego wykresu za pomocą powyższego kodu

Jeśli spojrzysz na powyższy obrazek, zobaczysz, że matplotlib próbuje wybrać kolory dla każdej linii, które są różne, ale ostatecznie ponownie wykorzystuje kolory - dziesięć górnych linii używa tych samych kolorów, co dziesięć dolnych. Chcę po prostu powstrzymać go od powtarzania już używanych kolorów ORAZ / LUB podać listę kolorów do użycia.

dlamotte
źródło

Odpowiedzi:

59

matplotlib 1.5+

Możesz użyć axes.set_prop_cycle( przykład ).

matplotlib 1.0-1.4

Możesz użyć axes.set_color_cycle( przykład ).

matplotlib 0.x

Możesz użyć Axes.set_default_color_cycle.

tom10
źródło
1
Więcej informacji na temat tego, czego szukałem ... Czy jest szansa, że ​​możesz dodać informacje o tym, jak użyć mapy kolorów do wygenerowania listy N kolorów?
dlamotte
19
@xyld - Nie chcę zbytnio podłączać własnej odpowiedzi, ale na dole tej odpowiedzi jest przykład: stackoverflow.com/questions/4805048/ ... Zasadniczo po prostu zrób to :, [colormap(i) for i in np.linspace(0, 0.9, num_plots)]gdzie colormapjest jedna z map kolorów matplotlib.pyplot.cmi numplotsjest liczbą unikalnych kolorów, które chcesz. Należy jednak pamiętać, że może to skutkować trudnymi do odróżnienia kolorami !!
Joe Kington,
4
Dobra odpowiedź Joe, i wydaje się, że odpowiada na pytanie xylda, więc zostawię to na tym. Warto jednak zauważyć, że istnieją dobre odpowiedzi na pytanie dotyczące generowania różnych kolorów, takie jak stackoverflow.com/questions/470690/ ...
tom10
Czy to działa na każdą fabułę? Wypróbowałem set_prop_cycle na Axes3D, a następnie użyłem pętli do wielu wykresów z ax.plot_wireframe (), ale 2 wykresy są pokolorowane tym samym kolorem.
Joonho Park
112

Zwykle używam drugiego z nich:

from matplotlib.pyplot import cm
import numpy as np

#variable n below should be number of curves to plot

#version 1:

color=cm.rainbow(np.linspace(0,1,n))
for i,c in zip(range(n),color):
   plt.plot(x, y,c=c)

#or version 2:

color=iter(cm.rainbow(np.linspace(0,1,n)))
for i in range(n):
   c=next(color)
   plt.plot(x, y,c=c)

Przykład 2: przykładowy wykres z iterem, następny kolor

Mark Amery
źródło
Użyłem nr 2. Mam listę kanałów, które muszę wykreślić, ale mogą one mieć różną długość. Zauważyłem, że ustawienie n = len na tej liście było bardzo pomocne w upewnieniu się, że wybrane kolory obejmują zakres i można odróżnić różnicę. Jeśli ta liczba jest zbyt wysoka, trudno dostrzec różnicę w kolorach.
fioletowo
Użyłem # 1, przydało się to z enumerate (list_name)
DevX
11

prop_cycle

color_cyclezostał wycofany w wersji 1.5 na korzyść tego uogólnienia: http://matplotlib.org/users/whats_new.html#added-axes-prop-cycle-key-to-rcparams

# cycler is a separate package extracted from matplotlib.
from cycler import cycler
import matplotlib.pyplot as plt

plt.rc('axes', prop_cycle=(cycler('color', ['r', 'g', 'b'])))
plt.plot([1, 2])
plt.plot([2, 3])
plt.plot([3, 4])
plt.plot([4, 5])
plt.plot([5, 6])
plt.show()

Pokazano również w (teraz źle nazwanym) przykładzie: http://matplotlib.org/1.5.1/examples/color/color_cycle_demo.html wspomnianym na: https://stackoverflow.com/a/4971431/895245

Przetestowano w matplotlib 1.5.1.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
źródło
9

Nie wiem, czy możesz automatycznie zmienić kolor, ale możesz wykorzystać swoją pętlę, aby wygenerować różne kolory:

for i in range(20):
   ax1.plot(x, y, color = (0, i / 20.0, 0, 1)

W takim przypadku kolory będą się różnić od czarnego do 100% zielonego, ale możesz je dostroić, jeśli chcesz.

Zobacz dokumentację matplotlib plot () i poszukaj colorargumentu słowa kluczowego.

Jeśli chcesz podać listę kolorów, po prostu upewnij się, że masz wystarczająco dużą listę, a następnie użyj indeksu pętli, aby wybrać kolor

colors = ['r', 'b', ...., 'w']

for i in range(20):
   ax1.plot(x, y, color = colors[i])
Andrea Spadaccini
źródło
1
Tak, chciałem uniknąć zrobienia czegoś takiego. Zajrzałem do map kolorów, ale jestem dość zdezorientowany, jak z nich korzystać.
dlamotte
Takie rozwiązanie nie daje łatwego sposobu na kontrolowanie mapy kolorów
Ryszard Cetnarski
Jest to bardzo dobre, szczególnie gdy set_prop_cycle zawiedzie. Nie wiem, dlaczego set_prop_cycle lub automatyczne kolorowanie nie działa w plot_wireframe () w Axes3D. Ale jest to rodzaj podstawowego / ręcznego rozwiązania do kolorowania.
Joonho Park
6

Możesz użyć predefiniowanej „jakościowej mapy kolorów” w następujący sposób:

from matplotlib.cm import get_cmap

name = "Accent"
cmap = get_cmap(name)  # type: matplotlib.colors.ListedColormap
colors = cmap.colors  # type: list
axes.set_prop_cycle(color=colors)

Przetestowano na matplotlib 3.0.3. Zobacz https://github.com/matplotlib/matplotlib/issues/10840, aby dowiedzieć się, dlaczego nie możesz zadzwonić axes.set_prop_cycle(color=cmap).

Lista predefiniowanych jakościowych map kolorów jest dostępna pod adresem https://matplotlib.org/gallery/color/colormap_reference.html :

Lista jakościowych map kolorów

nyanpasu64
źródło
Zwróć uwagę, że na nich przyjmuje pierwsze 3 kolory w kolejności
Ben Jones
2

Możesz także zmienić domyślny cykl kolorów w matplotlibrcpliku. Jeśli nie wiesz, gdzie jest ten plik, wykonaj następujące czynności w Pythonie:

import matplotlib
matplotlib.matplotlib_fname()

Spowoduje to wyświetlenie ścieżki do aktualnie używanego pliku matplotlibrc. W tym pliku znajdziesz pośród wielu innych ustawień także to dla axes.color.cycle. Po prostu wprowadź żądaną sekwencję kolorów, a znajdziesz ją na każdej działce, którą stworzysz. Zauważ, że możesz także użyć wszystkich prawidłowych nazw kolorów HTML w matplotlib.

Thomasillo
źródło
0

Jak zauważa odpowiedź Ciro , możesz użyć prop_cycledo ustawienia listy kolorów, przez które matplotlib będzie się przełączać. Ale ile kolorów? A co, jeśli chcesz użyć tego samego cyklu kolorów dla wielu wykresów, z różną liczbą linii?

Jedną z taktyk byłoby użycie formuły podobnej do tej z https://gamedev.stackexchange.com/a/46469/22397 , aby wygenerować nieskończoną sekwencję kolorów, w której każdy kolor stara się znacznie różnić od wszystkich, które go poprzedzały.

Niestety, prop_cyclenie przyjmie nieskończonych sekwencji - zawiesi się na zawsze, jeśli ją zdasz. Ale możemy wziąć, powiedzmy, pierwsze 1000 kolorów wygenerowanych z takiej sekwencji i ustawić je jako cykl kolorów. W ten sposób w przypadku działek z dowolną rozsądną liczbą linii należy uzyskać rozróżnialne kolory.

Przykład:

from matplotlib import pyplot as plt
from matplotlib.colors import hsv_to_rgb
from cycler import cycler

# 1000 distinct colors:
colors = [hsv_to_rgb([(i * 0.618033988749895) % 1.0, 1, 1])
          for i in range(1000)]
plt.rc('axes', prop_cycle=(cycler('color', colors)))

for i in range(20):
    plt.plot([1, 0], [i, i])

plt.show()

Wynik:

Wykres wyjściowy za pomocą powyższego kodu

Teraz wszystkie kolory są inne - chociaż przyznaję, że trudno mi rozróżnić kilka z nich!

Mark Amery
źródło