微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

单击感兴趣的Y轴值以调整颜色条

如何解决单击感兴趣的Y轴值以调整颜色条

我正在尝试调整程序,以增加条形图的交互性,因此,当我单击Y轴并选择一个新的感兴趣的值时,条形的颜色将进行相应的调整。我非常感谢这方面的帮助,因为我是python的新手,我不知道为什么单击图表时功能Clickchart()无法正常工作。

这是我的代码

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import scipy.stats as stats
import matplotlib 
import ipywidgets as wdg
from scipy.stats import norm
import matplotlib.gridspec as gridspec
from IPython.display import display
from matplotlib.cm import ScalarMappable


np.random.seed(12345)

#Raw Data

data = pd.DataFrame( { '1992': np.random.normal(32000,200000,3650),'1993': np.random.normal(43000,100000,'1994': np.random.normal(43500,140000,'1995': np.random.normal(48000,70000,3650) } ) 

#Mean of data
mean=data.mean(axis=0)

#Margin error of the standard error of the mean
sem=data.sem(axis=0)*1.96

    
# Create lists for the plot
year = ['1992','1993','1994','1995']
x_pos = np.arange(len(year))

#Assume the user provides the y axis value of interest as a parameter or variable


my_cmap = matplotlib.cm.get_cmap('seismic')

#Y = int(input("Enter y axis value of interest: "))

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

Y=42000

fig = plt.figure()
ax = fig.add_subplot(111)

#fig,ax = plt.subplots()

i=0

def get_color(y,m,ci):
    low = m-ci
    high = m+ci
    if y<=low:
        out = 1-1e-10
    elif y>=high:
        out = 0
    else:
        out = 1-(y-low)/(high-low)
    return out

c_list=[my_cmap(get_color(Y,mean[i],sem[i])) for i in range(4)]

    
# Build the initial plot

i=0    
while i < 4:
    bars=ax.bar(x_pos[i],yerr=sem[i],color=c_list[i],align='center',alpha=0.5,ecolor='black',capsize=10)
    i=i+1    

#Set the labels for the Visualization 
ax.set_ylabel('Mean of the Sample Data')
ax.set_xticks(x_pos)
ax.set_xticklabels(year)
ax.set_title('Custom Visualization of a Sample Data')
plt.axhline(y=Y,color = 'black')
#plt.text(3.7,Y,Y)
#plt.text(3.7,Y-2500,"Value of Interest")
ax.yaxis.grid(True)    

#Formats color bar
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)

# Show the figure
plt.show()    
    
#Interactivity
class ClickChart(object):
    
    def __init__(self,ax):
        self.fig=ax.figure
        self.ax = ax
        self.horiz_line = ax.axhline(y=Y,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=cmap(self.calc_prob(index)))
            print(index)
    
    def calc_prob(self,index):
        global mean,sem
        mean2 = mean[index]
        err = sem[index]
        result = norm.cdf(self.ypress,loc=mean2,scale=err) 
        return result
click=ClickChart(ax)  ~~~

解决方法

您基本上有两个问题:

1。您需要调用figure.canvas.draw()内部的onclick才能显示更改。

2。绘制条形图的方式不好,可以集体绘制它们,但是我没有更改该部分,我只是对您的代码做了一些最少的编辑以使其运行。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import scipy.stats as stats
import matplotlib 
from scipy.stats import norm
import matplotlib.gridspec as gridspec
from matplotlib.cm import ScalarMappable


np.random.seed(12345)

#Raw Data

data = pd.DataFrame( { '1992': np.random.normal(32000,200000,3650),'1993': np.random.normal(43000,100000,'1994': np.random.normal(43500,140000,'1995': np.random.normal(48000,70000,3650) } ) 

#Mean of data
mean=data.mean(axis=0)

#Margin error of the standard error of the mean
sem=data.sem(axis=0)*1.96

    
# Create lists for the plot
year = ['1992','1993','1994','1995']
x_pos = np.arange(len(year))

#Assume the user provides the y axis value of interest as a parameter or variable


my_cmap = matplotlib.cm.get_cmap('seismic')

Y=42000

fig = plt.figure()
ax = fig.add_subplot(111)
i=0
def get_color(y,m,ci):
    low = m-ci
    high = m+ci
    if y<=low:
        out = 1-1e-10
    elif y>=high:
        out = 0
    else:
        out = 1-(y-low)/(high-low)
    return out

c_list=[my_cmap(get_color(Y,mean[i],sem[i])) for i in range(4)]

i=0
# I think you need four bars,I dont think plotting individual bar is good
bars = []
while i < 4:
    bc=ax.bar(x_pos[i],yerr=sem[i],color=c_list[i],align='center',alpha=0.5,ecolor='black',capsize=10)
    bars.append(bc[0])
    i=i+1    

#Set the labels for the Visualization 
ax.set_ylabel('Mean of the Sample Data')
ax.set_xticks(x_pos)
ax.set_xticklabels(year)
ax.set_title('Custom Visualization of a Sample Data')
plt.axhline(y=Y,color = 'black')
#plt.text(3.7,Y,Y)
#plt.text(3.7,Y-2500,"Value of Interest")
ax.yaxis.grid(True)    

#Formats color bar
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)

# Show the figure
plt.show()    
    
#Interactivity
class ClickChart(object):
    
    def __init__(self,ax):
        self.fig=ax.figure
        self.ax = ax
        self.horiz_line = ax.axhline(y=Y,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)
        self.color_bar(event)
        # pls add this line
        self.fig.canvas.draw()

    def color_bar(self,event):
        for index,bar in enumerate(bars):
            # should use my_cmap,not cmap
            bar.set_color(c=my_cmap(self.calc_prob(index)))
            print(index)
    
    def calc_prob(self,index):
        global mean,sem
        mean2 = mean[index]
        err = sem[index]
        result = norm.cdf(self.ypress,loc=mean2,scale=err) 
        return result
click=ClickChart(ax)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。