简体   繁体   English

Matplotlib 交互式条形图

[英]Matplotlib interactive bar chart

I am trying to explore interactive feature in matplotlib, basically user picks ay value by clicking on the graph, depending on the value the user picked, a horizontal line is drawn.我正在尝试探索 matplotlib 中的交互功能,基本上用户通过单击图形来选择 y 值,根据用户选择的值,绘制一条水平线。 And according to that line the color of barchart should change (how far is the value from the mean).根据那条线,条形图的颜色应该改变(值与平均值相差多远)。

My program draws the user picked value but the color of bars do not change according.我的程序绘制用户选择的值,但条的颜色不会相应改变。 The click event calls my compare value function which draws the line but do not change color.单击事件调用我的比较值函数,该函数绘制线条但不改变颜色。 My code is as follows, any help would be appreciated我的代码如下,任何帮助将不胜感激

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


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])
df=df.T
n = len(df)
std = df.std()
means = df.mean() 


ci = (1.96*std/(n**0.5))
cu = list(means + ci)
cl = list(means - ci)
yerror = list(zip(cl , cu))
lab =list(df.columns)
x = np.arange(len(lab))


my_cmap = plt.cm.get_cmap('coolwarm')
norm = mpl.colors.Normalize(vmin=0.,vmax=1.)


def cmp_val(n):
    data_c=list((n - means))
    data_c = [x / max(data_c) for x in data_c]
    for i in range(len(data_c)):
        if data_c[i] > 0:
            my_cmap = plt.cm.get_cmap('Blues')
            colors = my_cmap(norm(data_c[i]))
            bar[i].set_facecolor(colors)
        if data_c[i] < 0:
            my_cmap = plt.cm.get_cmap('Reds')
            colors = my_cmap(norm(data_c[i]*-1))
            bar[i].set_facecolor(colors)
    plt.axhline(y=n, xmin=0, xmax=1, c = 'lightslategray', linestyle = ':')

    return n


plt.figure()
bar=plt.bar(x ,list(means), width=x[1]-x[0], edgecolor='black',  yerr= ci,capsize= 20)
plt.xticks(x, lab)

def onclick(event):
    plt.cla()
    bar=plt.bar(x ,list(means), width=x[1]-x[0], edgecolor='black',  yerr= ci,capsize= 20)
    cmp_val(event.ydata)

    plt.gca().set_title('{}'.format(event.ydata))
    plt.xticks(x, lab)

plt.gcf().canvas.mpl_connect('button_press_event', onclick)

plt.show()

I'm not sure I understood how you wanted to normalize your color coding, but I rewrote your code to make it work.我不确定我是否理解您想如何规范您的颜色编码,但我重写了您的代码以使其正常工作。 Hopefully you'll be able to adapt the code to your needs:希望您能够根据需要调整代码:

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

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])
df = df.T
n = len(df)
std = df.std()
means = df.mean()

ci = (1.96 * std / (n ** 0.5))
cu = list(means + ci)
cl = list(means - ci)
yerror = list(zip(cl, cu))
lab = list(df.columns)
x = np.arange(len(lab))

my_cmap = plt.cm.get_cmap('coolwarm_r')
my_norm = mcolors.Normalize(vmin=-means.max(), vmax=means.max())


def color_bars(val, rectangles, cmap, norm):
    heights = np.array([b.get_height() for b in rectangles])
    diff = heights - val
    colors = cmap(norm(diff))
    for rectangle, color in zip(rectangles, colors):
        rectangle.set_facecolor(color)
    fig.canvas.draw()


fig, ax = plt.subplots()
bars = ax.bar(x, means, width=x[1] - x[0], edgecolor='black', yerr=ci, capsize=20)
hline = ax.axhline(y=0, c='lightslategray', linestyle=':')
ax.set_xticks(x)
ax.set_xticklabels(lab)


def onclick(event):
    if event.inaxes:
        ax.set_title('{:.2f}'.format(event.ydata))
        hline.set_ydata([event.ydata, event.ydata])
        color_bars(event.ydata, bars, cmap=my_cmap, norm=my_norm)
        fig.canvas.draw()


fig.canvas.mpl_connect('button_press_event', onclick)

plt.show()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM