如何将颜色条添加到plt.bar图表?

时间:2020-09-16 06:20:32

标签: python pandas numpy matplotlib math

我正在尝试创建一个自我更新图表,该图表根据感兴趣的y轴值显示水平线和颜色条。因此,如果条绝对高于此值(给定95%置信区间),则条可能会被涂成红色;如果条绝对低于此值,则条可能会被涂成蓝色;如果包含该值,则条可能被涂成白色。类似于以下内容:

plot with colorbar

我的问题是我无法在绘图上显示颜色栏。我设法根据LinearSegmentedColormap和一些条件为每个彩条着色,但是我无法在图像上显示此彩条。

这是我的代码:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from math import sqrt
import matplotlib.axes
from matplotlib import cm
from matplotlib.colors import ListedColormap, LinearSegmentedColormap
from matplotlib.cm import ScalarMappable
np.random.seed(12345)

df = pd.DataFrame([np.random.normal(32000,200000,3650), 
                   np.random.normal(43000,100000,3650), 
                   np.random.normal(43500,140000,3650), 
                   np.random.normal(48000,70000,3650)], 
                  index=[1992,1993,1994,1995])

means = []
for i in df.index:
    means.append(df.loc[i].mean())
    
std = []
for i in df.index:
    std.append(df.loc[i].std())

# compute the 95% confidence intervals
conf = []
for i in range(len(means)):
    margin = (1.96*std[i])/sqrt(len(df.columns))
    conf.append(margin)
fig, axs = plt.subplots(1)
bars = plt.bar(df.index, means, yerr= conf, tick_label = df.index, capsize = 10)

#Setup the plot
yinterest = 43000
plt.gca().spines.get('top').set_visible(False)
plt.gca().spines.get('right').set_visible(False)
plt.axhline(yinterest, color  = 'black', label = '4300')

#setting the y-interest tick
plt.draw()
labels = [w.get_text() for w in ax.get_yticklabels()]
locs=list(ax.get_yticks())
labels+=[str(yinterest)]
locs+=[float(yinterest)]
ax.set_yticklabels(labels)
ax.set_yticks(locs)
plt.draw()

#setting up the colormap
colormap = cm.get_cmap('RdBu', 10)
colores = []
for i in range(len(means)):
    color = (yinterest-(means[i]-conf[i]))/((means[i]+conf[i])-(means[i]-conf[i]))
    bars[i].set_color(colormap(color))

对于python(或与此相关的程序设计),我是一个相当陌生的人,我到处都在寻找解决方案,但无济于事。任何帮助将不胜感激。

问候。

1 个答案:

答案 0 :(得分:0)

第一个提示是使用 pandasonic 方法来计算绘图数据 (更加简洁):

means = df.mean(axis=1)
std = df.std(axis=1)
conf = (std * 1.96 / sqrt(df.shape[1]))

并绘制您的图,运行:

yinterest = 39541
fig, ax = plt.subplots(figsize=(10,6))
ax.spines.get('top').set_visible(False)
ax.spines.get('right').set_visible(False)
colors = (yinterest - (means - conf)) / (2 * conf)
colormap = plt.cm.get_cmap('RdBu', 10)
plt.bar(df.index, means, yerr=conf, tick_label=df.index, capsize=10, color=colormap(colors))
cbar = plt.colorbar(plt.cm.ScalarMappable(cmap=colormap), orientation='horizontal')
cbar.set_label('Color', labelpad=5)
plt.axhline(yinterest, color='black', linestyle='--', linewidth=1)
plt.show()

一个技巧,可以避免在条形之后给条形着色 我计算的是颜色,然后将其转换为 彩色地图并传递到 plt.bar

要绘制颜色条,请使用 plt.colorbar

我将 yinterest 的值更改为您图片中包含的值,并得到了 类似于您的图片,但带有颜色条:

enter image description here