2012-08-13 136 views
46

我剛開始使用pandas/matplotlib作爲Excel的替代品來生成堆疊條形圖。我遇到了一個問題如何給熊貓/ matplotlib條形圖自定義顏色

(1)默認顏色映射中只有5種顏色,所以如果我有5個以上的類別,那麼顏色會重複。我怎樣才能指定更多的顏色?理想情況下,具有開始顏色和結束顏色的漸變以及在兩者之間動態生成n種顏色的方法?

(2)顏色看起來不是很悅目。我如何指定一組自定義的n種顏色?或者,一個漸變也會起作用。

其示出上述兩個點的一個例子是下面:

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) 

和輸出是這樣的:

enter image description here

+0

有一個非常簡單的方式來獲得部分顏色表。 [請參閱下面的解決方案](https://stackoverflow.com/a/47146928/3707607) – 2017-11-06 22:30:41

回答

69

可以直接指定color選項作爲列表提供給plot功能。

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) 

要定義自己的自定義列表,你可以做以下幾,或者只是仰望的Matplotlib技術通過其RGB值等定義顏色項目你可以得到你想要的那麼複雜有了這個。

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. 

最後一個例子產生了跟隨的顏色簡單的梯度對我來說:

enter image description here

我沒有用它足夠長的時間玩弄清楚如何強制傳說拿起定義的顏色,但我相信你可以做到這一點。

一般來說,一個很大的建議是直接使用Matplotlib中的函數。從Pandas調用它們是可以的,但我發現你可以從Matplotlib中獲得更好的選項和性能。

+3

小錯誤:my_colors = [cycle(['b','r','g','y','k' ])。next()for i in range(len(df))]將在python 2.7中每次給出'b'。你應該使用list(islice(cycle(['b','r','g','y','k']),None,len(df)))。 – vkontori 2012-12-20 09:15:41

+0

謝謝,我可能不會抓到那個。另一種選擇是先創建循環,然後在理解中調用其「next」函數。 – ely 2012-12-20 13:17:14

+0

是的。 it = cycle(['b','r','g','y','k']); my_colors = [next(it)for my in xrange(len(df))]也會將其切割爲... – vkontori 2012-12-20 22:53:45

26

我發現最簡單的方法就是與預設的色彩漸變的一個使用colormap參數.plot()

df.plot(kind='bar', stacked=True, colormap='Paired') 

enter image description here

你可以找到一個大list of preset colormaps here

colormaps

1

有關創建自己的colormaps更詳細的解答,我強烈建議您訪問this page

如果答案是太多的工作,你可以迅速使自己的顏色列表,並將它們傳遞給color參數。所有的顏色映射都在cm matplotlib模塊中。讓我們從反轉的地獄色彩地圖中獲得30個RGB(加alpha)顏色值的列表。爲此,首先獲取顏色貼圖並將其傳遞給0到1之間的一系列值。這裏,我們使用np.linspace在.4和.8之間創建30個代表顏色貼圖部分的等間隔值。

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.  ], 
     ..... 

然後,我們可以用它來繪製 - 使用來自原帖中的數據:

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)) 

enter image description here