首页 > 解决方案 > 根据鼠标按下事件更改图表条的颜色

问题描述

我正在尝试创建一个交互式条形图,当用户选择一个值(基于鼠标单击)时,图表的条形会改变颜色。所选值显示在图表底部,条形图应根据所选值高于或低于样本平均值的概率来改变颜色。

我被酒吧的颜色困住了。当我点击图表时,只有第一个栏会改变颜色,然后不会随着后续点击而更新。

总体预期结果是允许根据鼠标单击事件选择多个值。然后打算在所选值处绘制水平线,然后根据所选值在样本均值范围内的概率对条形图重新着色。这是在 jupyter 中运行的。

我对此仍然很陌生,因此当然感谢您提出的任何建议。

import numpy as np
from scipy import stats
from scipy.stats import norm
import math
import matplotlib.gridspec as gridspec
import matplotlib.pyplot as plt
import ipywidgets as wdg
from matplotlib.cm import ScalarMappable

%matplotlib notebook

###Set up dummy data
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])

###Calculate statistics incl confidence interval for the mean.  Calculate 97.5% interquantile range of the normal distribution (being 1.96 x standard error)
df =  df.T
stats = df.describe(percentiles = [0.025, 0.25, 0.5, 0.75, 0.975])
mean = stats.loc['mean']
onesd_meanerror = df.sem(axis = 0)
error_low = onesd_meanerror*1.96
error_high = onesd_meanerror*1.96

###Setup initial chart and plot bar chart
fig = plt.figure()
ax = fig.add_subplot(111)
x_axis_label = df.columns.values
plt.xticks(x_axis_label)

bars = (ax.bar(x_axis_label, mean, width=0.85, alpha=0.9, align='center',
                yerr = (error_low, error_high), error_kw={'capsize': 10, 'elinewidth': 2, 'alpha':1}))

###Create and display textarea widget
txt = wdg.Textarea(
    value='',
    placeholder='',
    description='Y Value:',
    disabled=False)
display(txt)

### Formats color bar.  Need the scalar mapable to enable use of the color bar.
my_cmap = plt.cm.get_cmap('coolwarm')
sm = ScalarMappable(cmap=my_cmap, norm=plt.Normalize(0,1))
sm.set_array([])
cbar = plt.colorbar(sm)
cbar.set_label('Probability', rotation=270,labelpad=25)

ydataselect = 40000

class ClickChart(object):

    def __init__(self, ax):
        self.fig=ax.figure
        self.ax = ax
        self.horiz_line = ax.axhline(y=ydataselect, color='black', linewidth=2)
        self.fig.canvas.mpl_connect('button_press_event', self.onclick)

### Event handlers
    def onclick(self, event):
        self.horiz_line.remove()
        self.ypress = event.ydata
        self.horiz_line = ax.axhline(y=self.ypress, color='red', linewidth=2)
        txt.value = str(event.ydata)
        self.color_bar(event)

    def color_bar(self, event):

        for index, bar in enumerate(bars):
            bar.set_color(c=my_cmap(self.calc_prob(index)))
            print(index)

    def calc_prob(self, index):
        global mean, onesd_meanerror
        mean = mean.iloc[index]
        err = onesd_meanerror.iloc[index]
        result = norm.cdf(self.ypress, loc=mean, scale=err)
        return result

click = ClickChart(ax)```

标签: pythonmatplotlibevent-handlingbar-chartcolorbar

解决方案


你是如此接近!问题是您正在重新mean定义calc_prob(). 进行更改以避免这种情况将修复代码并提供您想要的行为:

def calc_prob(self, index):
    global mean, onesd_meanerror
    mean2 = mean.iloc[index] # Changed
    err = onesd_meanerror.iloc[index]
    result = norm.cdf(self.ypress, loc=mean2, scale=err) # Changed
    return result

动态图


推荐阅读