这是为了扩展我从网址Update (or redraw?) matplotlib bar chart using y value from onclick
复制的现有示例的功能我添加了代码以绘制带有y值的线。 onpick时,它会与y值画一条线,问题是如何在多次选择后清除以前的y值????
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from scipy.stats import ttest_1samp
import matplotlib.transforms as transforms
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])
class PointPicker(object):
def __init__(self, df, y=0):
# Store reference to the dataframe for access later
self.df = df
# moments for bar chart "box plot"
mus = df.mean(axis=1)
sigmas = df.std(axis=1)
obs = df.count(axis=1)
ses = sigmas / np.sqrt(obs - 1)
err = 1.96 * ses
Nvars = len(df)
# map t-ststistics to colors
ttests = ttest_1samp(df.transpose(), y)
RdBus = plt.get_cmap('RdBu')
colors = RdBus(1 / (1 + np.exp(ttests.statistic)))
self.fig = plt.figure()
self.ax = self.fig.add_subplot(111)
# added line with y-values
self.line = self.ax.axhline(y=y, color='red', label='Old')
trans = transforms.blended_transform_factory(
self.ax.get_yticklabels()[0].get_transform(), self.ax.transData)
self.ax.text(0, y, "{:.0f}".format(y), color="red", transform=trans, ha="right", va="center")
# bar chart "box plot". Store reference to the bars here for access later
self.bars = self.ax.bar(
list(range(Nvars)), mus, yerr=ses, capsize=20, picker=5, color=colors)
plt.xticks(list(range(Nvars)), df.index)
plt.tick_params(top='off', bottom='off', left='off', right='off', labelleft='on', labelbottom='on')
plt.gca().get_yaxis().set_major_formatter(matplotlib.ticker.FuncFormatter(lambda x, p: format(int(x), ',')))
plt.title('Random Data for 1992 to 1995')
self.fig.canvas.mpl_connect('pick_event', self.onpick)
self.fig.canvas.mpl_connect('key_press_event', self.onpress)
def onpress(self, event):
"""define some key press events"""
if event.key.lower() == 'q':
sys.exit()
def onpick(self,event):
x = event.mouseevent.xdata
y = event.mouseevent.ydata
# If a line already exists, just update its y value, else create a horizontal line
try:
self.line.set_ydata(y)
except:
self.line = self.ax.axhline(y=y, color='red')
# added line with y-values, how to clear previous y values?????
trans = transforms.blended_transform_factory(
self.ax.get_yticklabels()[0].get_transform(), self.ax.transData)
self.ax.text(0, y, "{:.0f}".format(y), color="red", transform=trans, ha="right", va="center")
# Recalculate the ttest
newttests = ttest_1samp(df.transpose(), y)
RdBus = plt.get_cmap('RdBu')
# Recalculate the colors
newcolors = RdBus(1 / (1 + np.exp(newttests.statistic)))
# Loop over bars and update their colors
for bar, col in zip(self.bars, newcolors):
bar.set_facecolor(col)
self.fig.canvas.draw()
if __name__ == '__main__':
#plt.ion()
p = PointPicker(df, y=32000)
plt.show()