0

Good Morning

I have done a bar graph, and I want than a line change of position in the graph bar with a mouse event. Im a novice and I couldn't get it to work, I put the code underneath.

import matplotlib.pyplot as plt
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['mean']=df.mean(axis=1)
df['std']=df.std(axis=1)
fig, ax = plt.subplots()
years = df.index.values.tolist()
averages = df['mean'].values.tolist()
stds =df['std'].values.tolist()
x_pos = np.arange(len(years))
min_value = int(df.values.min())
max_value =int(df.values.max())
yaxis = np.arange(min_value,max_value, 100)
plt.bar(x_pos,averages, color='red')
ax.set_xticks(x_pos)
ax.set_xticklabels(years)
ax.set_ylabel('Values')
ax.set_title('Average values per year')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
line = ax.axhline(y=10000,color='black')
traza=[]

def onclick(event):
    if not event.inaxes:
            return
    traza.append('onclick '+event.ydata())
    line.set_data([0,1], event.ydata())

plt.connect('button_press_event', onclick)


plt.show()

I can't even get the onclick procedure done. Could you help me?

Thank you

Dembora
  • 3
  • 2

1 Answers1

0

Several things are going wrong:

  • event.ydata is not a function, so you can't call it as event.ydata(). Just use it directly.
  • When some graphical information changes, the image on the screen isn't updated immediately (as there can be many changes and redrawing continuously could be very slow). After all changes are done, calling fig.canvas.draw() will update the screen.
  • 'onclick ' + event.ydata doesn't work. 'onclick ' is a string and ydata is a number. To concatenate a string and a number, first convert the number to a string: 'onclick ' + str(event.ydata)
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

def onclick(event):
    if not event.inaxes:
        return
    line.set_data([0, 1], event.ydata)
    fig.canvas.draw()

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['mean'] = df.mean(axis=1)
df['std'] = df.std(axis=1)
fig, ax = plt.subplots()
years = df.index.values.tolist()
averages = df['mean'].values.tolist()
stds = df['std'].values.tolist()
x_pos = np.arange(len(years))
min_value = int(df.values.min())
max_value = int(df.values.max())
yaxis = np.arange(min_value, max_value, 100)
plt.bar(x_pos, averages, color='red')
ax.set_xticks(x_pos)
ax.set_xticklabels(years)
ax.set_ylabel('Values')
ax.set_title('Average values per year')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
line = ax.axhline(y=10000, color='black', linestyle=':')

plt.connect('button_press_event', onclick)
plt.show()
JohanC
  • 71,591
  • 8
  • 33
  • 66
  • Thank you very much for your answer. I've made the changes you suggested. But I think that for some reason the onclick procedure is never executed. In fact, if it did, I would have seen some of the errors you pointed out. – Dembora Jul 02 '20 at 12:45
  • This can depend on your environment. If you're running inside a jupyter notebook, you may need `%matplotlib notebook` (not `%matplotlib inline`, which shows the plots without interactivity, see e.g. [this post](https://stackoverflow.com/questions/43923313/canvas-mpl-connect-in-jupyter-notebook)). Or you could run inside an interactive environment such as PyCharm. – JohanC Jul 02 '20 at 13:28
  • Thank you, I found out which was the problem with your last comment. – Dembora Jul 03 '20 at 09:27