Reputation: 2161
I have the following class that draws a vertical line through the y-axis, so that when I click on it a horizontal line gets drawn at the location. My goal is to get the y-coordinate to actually print right at the y-axis where the horizontal line gets drawn. For testing, I am trying to print a title with the y-ccordinate, but it is not working as expected.
What I am trying to really accomplish is to make the y-axis on a bar plot clickable so that the user can select a point on the y-axis, and then a bunch of "stuff" happens (including the drawing of a horizontal line). I really see no other way to make this happen, other than drawing a plottable vertical line through the y-axis to make it pickable. This seems rather kludgey, but I have not had any success with any other methods.
import matplotlib.pyplot as plt
class PointPicker(object):
def __init__(self):
self.fig = plt.figure()
self.ax = self.fig.add_subplot(111)
self.lines2d, = self.ax.plot((0, 0), (-6000, 10000), 'k-', linestyle='-',picker=5)
self.fig.canvas.mpl_connect('pick_event', self.onpick)
self.fig.canvas.mpl_connect('key_press_event', self.onpress)
fig.canvas.mpl_connect('button_press_event', self.onclick)
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
L = self.ax.axhline(y=y)
print(y)
ax.axvspan(0, 0, facecolor='y', alpha=0.5, picker=10)
self.fig.canvas.draw()
def onclick(event):
self.fig.canvas.set_title('Selected item came from {}'.format(event.ydata))
print(event.xdata, event.ydata)
if __name__ == '__main__':
plt.ion()
p = PointPicker()
plt.show()
Assuming there is no ther way to achieve my end result, all is well with this method, except I cannot for the life of me get the title to print (using the self.fig.canvas.set_title('Selected item came from {}'.format(event.ydata)
).
Upvotes: 0
Views: 2167
Reputation: 339052
You can use the 'button_press_event'
to connect to a method, which verifies that the click has happened close enough to the yaxis spine and then draws a horizontal line using the clicked coordinate.
import matplotlib.pyplot as plt
class PointPicker(object):
def __init__(self, ax, clicklim=0.05):
self.fig=ax.figure
self.ax = ax
self.clicklim = clicklim
self.horizontal_line = ax.axhline(y=.5, color='y', alpha=0.5)
self.text = ax.text(0,0.5, "")
print self.horizontal_line
self.fig.canvas.mpl_connect('button_press_event', self.onclick)
def onclick(self, event):
if event.inaxes == self.ax:
x = event.xdata
y = event.ydata
xlim0, xlim1 = ax.get_xlim()
if x <= xlim0+(xlim1-xlim0)*self.clicklim:
self.horizontal_line.set_ydata(y)
self.text.set_text(str(y))
self.text.set_position((xlim0, y))
self.fig.canvas.draw()
if __name__ == '__main__':
fig = plt.figure()
ax = fig.add_subplot(111)
ax.bar([0,2,3,5],[4,5,1,3], color="#dddddd")
p = PointPicker(ax)
plt.show()
Upvotes: 4