2012-08-13 155 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