'Event Pick to update BarChart Attributes
New to the forum!
I’m trying to create an interactive barchart for a homework problem – I am wondering where I am going wrong with out using some one else's solution (like this awesome code here!)
I click on the chart to generate a reference line with a new y value and to change the color of the bar. For simplicity, I’m debugging using just two colors and comparing to the mean (when y >mean, y<mean). Aside from the two codes below, I've tried to clear the chart and re-draw it within the onclick function and to write a separate function, although not sure how to call it... Any guidance would be much appreciated - I'm not sure how the pieces fit together, so its hard to break it down for troubleshooting.
df=pd.DataFrame({'mean':[40000,50000,20000,60000,3000],'CI':[4000,4000,3000,1000,200]},index=['A','B','C','D','E'])
df=df.T
fig, ax = plt.subplots()
bars = ax.bar([1,2,3,4,5], df.loc['mean'])
#Set horizontal line
hline = ax.axhline(y=20000, c='red', linestyle='--')
ax.set_xticks([1,2,3,4,5])
ax.set_xticklabels(df.columns)
def onclick(event):
hline.set_ydata([event.ydata, event.ydata])
df2.loc['y']=event.ydata
for val in df2.loc['y']:
if df2.loc['y'] < df2.loc['mean']:
col.append('red')
else:
col.append('white')
fig.canvas.mpl_connect('button_press_event', onclick)
Also tried
def onclick(event):
#provide y data, based on where clicking. Note to self: 'xdata' would give slanted line
hline.set_ydata([event.ydata, event.ydata])
df2.loc['y']=event.ydata
for bar in bars:
if event.ydata < df2.loc['mean']:
bar.set_color('red')
else:
bar.set_color('white')
return result
Solution 1:[1]
The main problem is that you never redraw the canvas, so every change you communicate to matplotlib will not appear in the figure generated by the backend. You also have to update the properties of the rectangles representing the bars - you tried this with bar.set_color() in one of the versions which changes both facecolor and edgecolor, intended or otherwise.
import pandas as pd
import matplotlib.pyplot as plt
df=pd.DataFrame({'mean':[40000,50000,20000,60000,3000],'CI':[4000,4000,3000,1000,200]},index=['A','B','C','D','E'])
df2=df.T
fig, ax = plt.subplots()
bars = ax.bar(range(df2.loc['mean'].size), df2.loc['mean'])
#Set horizontal line
hline = ax.axhline(y=20000, c='red', linestyle='--')
ax.set_xticks(range(df2.columns.size), df2.columns)
def onclick(event):
#update hline position
hline.set_ydata([event.ydata])
#change all rectangles that represent the bars
for bar in bars:
#retrieve bar height and compare
if bar.get_height() > event.ydata:
#to set the color
bar.set_color("red")
else:
bar.set_color("white")
#redraw the figure to make changes visible
fig.canvas.draw_idle()
fig.canvas.mpl_connect('button_press_event', onclick)
plt.show()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |

