Właśnie zacząłem używać pandas / matplotlib jako zamiennika programu Excel do generowania skumulowanych wykresów słupkowych. Mam problem
(1) w domyślnej mapie kolorów jest tylko 5 kolorów, więc jeśli mam więcej niż 5 kategorii, kolory się powtarzają. Jak mogę określić więcej kolorów? Idealnie, gradient z kolorem początkowym i końcowym oraz sposób na dynamiczne generowanie n kolorów pomiędzy nimi?
(2) kolory nie są zbyt przyjemne wizualnie. Jak określić niestandardowy zestaw n kolorów? Lub też zadziałałby gradient.
Przykład ilustrujący oba powyższe punkty znajduje się poniżej:
4 from matplotlib import pyplot
5 from pandas import *
6 import random
7
8 x = [{i:random.randint(1,5)} for i in range(10)]
9 df = DataFrame(x)
10
11 df.plot(kind='bar', stacked=True)
A wynik jest taki:
python
matplotlib
pandas
vasek1
źródło
źródło
Odpowiedzi:
Możesz określić
color
opcję jako listę bezpośrednio dlaplot
funkcji.from matplotlib import pyplot as plt from itertools import cycle, islice import pandas, numpy as np # I find np.random.randint to be better # Make the data x = [{i:np.random.randint(1,5)} for i in range(10)] df = pandas.DataFrame(x) # Make a list by cycling through the colors you care about # to match the length of your data. my_colors = list(islice(cycle(['b', 'r', 'g', 'y', 'k']), None, len(df))) # Specify this list of colors as the `color` option to `plot`. df.plot(kind='bar', stacked=True, color=my_colors)
Aby zdefiniować własną listę niestandardową, możesz wykonać kilka następujących czynności lub po prostu sprawdzić techniki Matplotlib służące do definiowania elementu koloru za pomocą wartości RGB itp. Możesz to zrobić tak skomplikowane, jak chcesz.
my_colors = ['g', 'b']*5 # <-- this concatenates the list to itself 5 times. my_colors = [(0.5,0.4,0.5), (0.75, 0.75, 0.25)]*5 # <-- make two custom RGBs and repeat/alternate them over all the bar elements. my_colors = [(x/10.0, x/20.0, 0.75) for x in range(len(df))] # <-- Quick gradient example along the Red/Green dimensions.
Ostatni przykład daje mi następujący prosty gradient kolorów:
Nie bawiłem się nim wystarczająco długo, aby wymyślić, jak zmusić legendę do wybrania określonych kolorów, ale jestem pewien, że możesz to zrobić.
Ogólnie rzecz biorąc, ważną radą jest po prostu bezpośrednie użycie funkcji z Matplotlib. Dzwonienie do nich z Pandas jest w porządku, ale uważam, że masz lepsze opcje i wydajność dzwoniąc do nich bezpośrednio z Matplotlib.
źródło
next
funkcji w zrozumieniu.pylab.ion()
interaktywnego pylab.Najłatwiejszym sposobem jest użycie
colormap
parametru w.plot()
jednym z gotowych gradientów kolorów:df.plot(kind='bar', stacked=True, colormap='Paired')
Możesz znaleźć dużą listę gotowych map kolorów tutaj .
źródło
Aby uzyskać bardziej szczegółową odpowiedź na temat tworzenia własnych map kolorów, gorąco zachęcam do odwiedzenia tej strony
Jeśli ta odpowiedź jest zbyt pracochłonna, możesz szybko stworzyć własną listę kolorów i przekazać je do
color
parametru. Wszystkiecm
mapy kolorów znajdują się w module matplotlib. Zdobądźmy listę 30 wartości kolorów RGB (plus alfa) z mapy kolorów odwróconego piekła. Aby to zrobić, najpierw pobierz mapę kolorów, a następnie przekaż jej sekwencję wartości od 0 do 1. Tutaj używamynp.linspace
do utworzenia 30 równo rozmieszczonych wartości między .4 a .8, które reprezentują tę część mapy kolorów.from matplotlib import cm color = cm.inferno_r(np.linspace(.4, .8, 30)) color array([[ 0.865006, 0.316822, 0.226055, 1. ], [ 0.851384, 0.30226 , 0.239636, 1. ], [ 0.832299, 0.283913, 0.257383, 1. ], [ 0.817341, 0.270954, 0.27039 , 1. ], [ 0.796607, 0.254728, 0.287264, 1. ], [ 0.775059, 0.239667, 0.303526, 1. ], [ 0.758422, 0.229097, 0.315266, 1. ], [ 0.735683, 0.215906, 0.330245, 1. ], .....
Następnie możemy użyć tego do wykreślenia, używając danych z oryginalnego postu:
import random x = [{i: random.randint(1, 5)} for i in range(30)] df = pd.DataFrame(x) df.plot(kind='bar', stacked=True, color=color, legend=False, figsize=(12, 4))
źródło
inferno_r
: matplotlib.org/examples/color/colormaps_reference.html