2013-05-30 11 views
30

Mam następujący problem, chcę utworzyć własną mapę kolorów (czerwony-mix-fioletowy-mix-niebieski), która odwzorowuje wartości od -2 do +2 i chce użyć to kolor punktów w mojej działce. Wykres powinien wówczas mieć kolorową skalę po prawej stronie.

W ten sposób tworzę mapę do tej pory. Ale nie jestem pewien, czy miesza kolory.Utwórz własną mapę kolorów przy użyciu matplotlib i skali kolorów wydruku

cmap = matplotlib.colors.ListedColormap(["red","violet","blue"], name='from_list', N=None) 
m = cm.ScalarMappable(norm=norm, cmap=cmap) 


W ten sposób mapuję kolory na wartości.

colors = itertools.cycle([m.to_rgba(1.22), ..]) 


Potem wykreślić go:

for i in range(0, len(array_dg)): 
    plt.plot(array_dg[i], markers.next(),alpha=alpha[i], c=colors.next()) 


Moje problemy to:
1. Nie mogę wykreślić skalę kolorów.
2. Nie jestem całkowicie pewien, czy moja skala tworzy ciągłą (gładką) skalę kolorów.

+0

mógłbyś wyjaśnić swoje pytanie trochę? Na przykład 'c =' określa kolor linii, podczas gdy mówisz o punktach. Możesz określić tylko jeden 'markerfacecolor', scatter może być lepszą opcją, jeśli naprawdę potrzebujesz punktów. I rzeczywiście lista 'ListedColormap' jest wymieniona, a nie ciągła, patrz' LinearSegmentedColormap'. –

+0

To dziwne, ma być punktami i wygląda jak punkty. – Trollbrot

+0

Możesz zejść z kursu, ale to właśnie powinieneś wyjaśnić. Nie możemy zobaczyć, jakiego stylu fabularnego używasz. Jeśli użyjesz 'plt.plot (value, 'o')', będziesz rysować tylko znaczniki i bez linii, ale znaczniki będą miały jeden stały kolor, który nie będzie (i nie będzie się różnić) w zależności od wartości. –

Odpowiedz

53

Istnieje przykład ilustrujący numer how to create custom colormaps here. Docstring jest niezbędny do zrozumienia znaczenia cdict. Gdy pojawi się, że pod pasem, można użyć cdict takiego:

cdict = {'red': ((0.0, 1.0, 1.0), 
        (0.1, 1.0, 1.0), # red 
        (0.4, 1.0, 1.0), # violet 
        (1.0, 0.0, 0.0)), # blue 

     'green': ((0.0, 0.0, 0.0), 
        (1.0, 0.0, 0.0)), 

     'blue': ((0.0, 0.0, 0.0), 
        (0.1, 0.0, 0.0), # red 
        (0.4, 1.0, 1.0), # violet 
        (1.0, 1.0, 0.0)) # blue 
      } 

Chociaż format, cdict daje dużą elastyczność, uważam za zwykłą gradienty jego format jest raczej nieintuicyjne. Oto funkcja narzędzie, aby pomóc generowania prostych LinearSegmentedColormaps:

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.colors as mcolors 


def make_colormap(seq): 
    """Return a LinearSegmentedColormap 
    seq: a sequence of floats and RGB-tuples. The floats should be increasing 
    and in the interval (0,1). 
    """ 
    seq = [(None,) * 3, 0.0] + list(seq) + [1.0, (None,) * 3] 
    cdict = {'red': [], 'green': [], 'blue': []} 
    for i, item in enumerate(seq): 
     if isinstance(item, float): 
      r1, g1, b1 = seq[i - 1] 
      r2, g2, b2 = seq[i + 1] 
      cdict['red'].append([item, r1, r2]) 
      cdict['green'].append([item, g1, g2]) 
      cdict['blue'].append([item, b1, b2]) 
    return mcolors.LinearSegmentedColormap('CustomMap', cdict) 


c = mcolors.ColorConverter().to_rgb 
rvb = make_colormap(
    [c('red'), c('violet'), 0.33, c('violet'), c('blue'), 0.66, c('blue')]) 
N = 1000 
array_dg = np.random.uniform(0, 10, size=(N, 2)) 
colors = np.random.uniform(-2, 2, size=(N,)) 
plt.scatter(array_dg[:, 0], array_dg[:, 1], c=colors, cmap=rvb) 
plt.colorbar() 
plt.show() 

enter image description here


By the way, for-loop

for i in range(0, len(array_dg)): 
    plt.plot(array_dg[i], markers.next(),alpha=alpha[i], c=colors.next()) 

Działki jeden punkt za każde wezwanie do plt.plot. Będzie to działać dla niewielkiej liczby punktów, ale stanie się bardzo powolne dla wielu punktów. plt.plot może rysować tylko w jednym kolorze, ale plt.scatter może przypisać inny kolor do każdej kropki. Tak więc, droga do przebycia to plt.scatter.

+0

Teraz mam problem. Chciałbym również otrzymać inny symbol znacznika w zależności od koloru (mam 13 różnych kolorów). Ale wykres punktowy pozwala tylko na jeden znacznik na fabułę, czy też coś przeoczyłem? – Trollbrot

+0

W takim przypadku będziesz musiał wywołać 'plt.scatter' (lub' plt.plot') raz dla każdej kombinacji kolorów/znaczników. – unutbu

+0

Dlaczego nie mogę użyć mapy kolorów utworzonej za pomocą tej niesamowitej funkcji w plt.set_cmap()? Błąd jest bardzo długi, ostatnia linia to ValueError: Niestandardowa mapa Colormap nie jest rozpoznawana. – Phlya

10

Jeśli chcesz zautomatyzować tworzenie niestandardowej rozbieżnej mapy kolorów powszechnie używanej w przypadku surface plots, ten moduł w połączeniu z metodą @unutbu działa dobrze dla mnie.

def diverge_map(high=(0.565, 0.392, 0.173), low=(0.094, 0.310, 0.635)): 
    ''' 
    low and high are colors that will be used for the two 
    ends of the spectrum. they can be either color strings 
    or rgb color tuples 
    ''' 
    c = mcolors.ColorConverter().to_rgb 
    if isinstance(low, basestring): low = c(low) 
    if isinstance(high, basestring): high = c(high) 
    return make_colormap([low, c('white'), 0.5, c('white'), high]) 

Wartości wysokie i niskie mogą być albo sznurek Nazwy kolorów RGB lub krotki. Jest to wynik używając surface plot demo: enter image description here

+0

Bardzo zadbana funkcja! – Thriveth

6

od metod stosowanych w innych odpowiedzi wydaje się dość skomplikowany dla takiego łatwego zadania, tutaj jest nowy odpowiedź:

Zamiast ListedColormap, która produkuje dyskretnej colormap, możesz użyć LinearSegmentedColormap.Można go łatwo utworzyć z listy przy użyciu metody from_list.

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.colors 

x,y,c = zip(*np.random.rand(30,3)*4-2) 

cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", ["red","violet","blue"]) 

plt.scatter(x,y,c=c, cmap=cmap) 
plt.colorbar() 
plt.show() 

enter image description here

+0

W jaki sposób można teraz przekazać temu zakresowi zdefiniowany zakres, np. że 'czerwony' odpowiada' -5', 'fioletowy' na' 1' i 'niebieski' na' 100'? Byłbym bardzo wdzięczny, gdybyś mógł spojrzeć na pytanie, które zadałem [tutaj] (https://stackoverflow.com/questions/47697782/how-to-create-a- customized-colormap-and-use-it-for- różne zakresy danych). – Cleb

+1

Używanie argumentów 'vmin' i' vmax' lub 'norm' dla danej metody drukowania. – ImportanceOfBeingErnest

Powiązane problemy