(python matplotlib)如何更改棒棒糖图中每个棒棒糖的颜色(ax.stem)

时间:2018-10-08 07:44:57

标签: python matplotlib colors

我正在使用ax.stem在python中绘制棒棒糖图。但是,我发现很难为每个棒棒糖分配不同的颜色 as shown here

如您所见,我有两个类别“ GWP”和“ FDP”。 在我的项目中,每个类别应分为4个子类别:“成分”,“废物”,“能源”和“基础设施”。因此,我想给它们分配不同的颜色以指示子类别。

这里提出了一个解决方案:https://python-graph-gallery.com/181-custom-lollipop-plot/

但这只会教您如何更改所有棒棒糖的颜色。

还有另一种解决方案:https://python-graph-gallery.com/183-highlight-a-group-in-lollipop/

但是这个并没有真正使用ax.stem

请让我知道如何为每个棒棒糖分配不同的颜色。

(而且,我也不知道为什么我的图显示为上下颠倒。而且,y轴未按顺序对齐,并且有一个点未用线连接。尽管它在我的原始图中正确显示)

这是我的代码:

#%%
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

plt.style.use('ggplot')


# my dataset
columns = np.array(['types', 'GWP100 (year)', 'FDP (year)'])


types = np.array(['Total (ingredient) per kg', 'Total (waste) per kg',
       'energy (whole process) per kg', 'Infrastructure', 'Total (Total)']).reshape(5,1)
gwp = np.array([  2.86982617e+02,   2.16824983e+02,   4.38920760e+01,
         6.02400000e-02,   5.47759916e+02]).reshape(5,1)
fdp = np.array([  1.35455867e+02,   7.02868322e+00,   1.26622560e+01,
         1.64568000e-02,   1.55163263e+02]).reshape(5,1)

original_data = np.concatenate((types, gwp, fdp), axis = 1)




# produce dataframe
data = pd.DataFrame(original_data, columns = columns)

#                           types GWP100 (year)  FDP (year)
#0      Total (ingredient) per kg    286.982617  135.455867
#1           Total (waste) per kg    216.824983  7.02868322
#2  energy (whole process) per kg     43.892076   12.662256
#3                 Infrastructure       0.06024   0.0164568
#4                  Total (Total)    547.759916  155.163263


#%%  graph
fig = plt.figure(1, figsize =(8,6))

# 1st subplot
ax1 = fig.add_subplot(1,2,1)
gwp = data[data.columns[1]]

ax1.stem(gwp)
ax1.set_ylabel(r'kg CO$_2$-Eq', fontsize=10)
ax1.set_xlabel('GWP', fontsize=10)


# 2nd subplot
ax2 = fig.add_subplot(1,2,2)
fdp = data[data.columns[2]]

ax2.stem(fdp)
ax2.set_ylabel(r'kg oil-Eq', fontsize = 10)
ax2.set_xlabel('FDP', fontsize=10)

2 个答案:

答案 0 :(得分:0)

我将回答有关线和标记类别相同颜色的主要问题之一。调用ax1.stem()根据官方文档指定颜色列表时,似乎没有直接选择。实际上,他们说,如果这样做,得出的情节可能并不合理。不过,以下是一种使事情按部就班的技巧。

想法如下:

  • 获取显示在子图上的对象(stemline
  • 获取标记的x-y数据
  • 查看数据并更改每个茎线的颜色。用与 stemline 相同的颜色分别绘制标记。 colors是一个数组,用于指定您选择的颜色。

以下是代码的相关部分:

# 1st subplot
ax1 = fig.add_subplot(1,2,1)
gwp = data[data.columns[1]]

colors = ['r', 'g', 'b', 'y', 'k']
_, stemlines, _ = ax1.stem(gwp)

line = ax1.get_lines()
xd = line[0].get_xdata()
yd = line[0].get_ydata()

# mec and mfc stands for markeredgecolor and markerfacecolor
for i in range(len(stemlines)):
    plt.plot([xd[i]], [yd[i]], 'o', ms=7, mfc=colors[i], mec=colors[i])
    plt.setp(stemlines[i], 'color', colors[i])

ax1.set_ylabel(r'kg CO$_2$-Eq', fontsize=10)
ax1.set_xlabel('GWP', fontsize=10)


# 2nd subplot
ax2 = fig.add_subplot(1,2,2)
fdp = data[data.columns[2]]

_, stemlines, _ = ax2.stem(fdp)

line = ax2.get_lines()
xd = line[0].get_xdata()
yd = line[0].get_ydata()

for i in range(len(stemlines)):
    plt.plot([xd[i]], [yd[i]], 'o', ms=7, mfc=colors[i], mec=colors[i])
    plt.setp(stemlines[i], 'color', colors[i])

enter image description here

答案 1 :(得分:0)

stem当前由几行和顶部由点组成的“线”组成。它没有选择在其界面内分别为线条着色的选项。

您可以复制茎图以使用所需的颜色手动绘制线条。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

columns = np.array(['types', 'GWP100 (year)', 'FDP (year)'])
types = np.array(['Total (ingredient) per kg', 'Total (waste) per kg',
       'energy (whole process) per kg', 'Infrastructure', 'Total (Total)'])
gwp = np.array([  2.86982617e+02,   2.16824983e+02,   4.38920760e+01,
         6.02400000e-02,   5.47759916e+02])
fdp = np.array([  1.35455867e+02,   7.02868322e+00,   1.26622560e+01,
         1.64568000e-02,   1.55163263e+02])

# produce dataframe
data = pd.DataFrame([types,gwp,fdp], index = columns).transpose()

colors = list("bgryk")

fig, (ax, ax2) = plt.subplots(ncols=2)

for t, y, c in zip(data["types"], data["GWP100 (year)"],colors):
    ax.plot([t,t], [0,y], color=c, marker="o", markevery=(1,2))
ax.set_ylim(0,None)
plt.setp(ax.get_xticklabels(), rotation=90)
fig.tight_layout()    
plt.show()

enter image description here

当然,更有效的解决方案是将LineCollection与点的散点图结合使用。

fig, (ax, ax2) = plt.subplots(ncols=2)

segs = np.zeros((len(data), 2, 2))
segs[:,:,0] = np.repeat(np.arange(len(data)),2).reshape(len(data),2) 
segs[:,1,1] = data["GWP100 (year)"].values

lc = LineCollection(segs, colors=colors)
ax.add_collection(lc)
ax.scatter(np.arange(len(data)), data["GWP100 (year)"].values, c=colors)
ax.set_xticks(np.arange(len(data)))
ax.set_xticklabels(data["types"], rotation=90)
ax.autoscale()
ax.set_ylim(0,None)
fig.tight_layout()
plt.show()