[英]Control the mouse click event with a subplot rather than a figure in matplotlib
I have a figure with 5 subplots. 我有一个包含5个子图的图。 I am using a mouse click event to create a shaded area in the 4th and 5th subplot only (see attached pic below). 我正在使用鼠标单击事件在第4和第5子图中创建阴影区域(请参见下面的附图)。
The mouse click event is triggered when I click on any of the subplots in the figure. 单击图中的任何子图时,将触发鼠标单击事件。 However, I would ideally like to be able to trigger the mouse click event only when clicked on the 4th and 5th subplots. 但是,我希望只有在点击第4和第5个子图时才能触发鼠标点击事件。 I am wondering if this is possible using mpl_connect. 我想知道使用mpl_connect是否可行。
Here's my code 这是我的代码
import numpy as np
from scipy.stats import norm, lognorm, uniform
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons, CheckButtons
from matplotlib.patches import Polygon
#####Mean and standard deviation#####
mu_a1 = 1
mu_b1 = 10
mu_c1 = -13
sigma_a1 = 0.14
sigma_b1 = 1.16
sigma_c1 = 2.87
mu_x01 = -11
sigma_x01 = 1.9
#####_____#####
#####Generating random data#####
a1 = 0.75*mu_a1 + (1.25 - 0.75)*sigma_a1*np.random.sample(10000)
b1 = 8*mu_b1 + (12 - 8)*sigma_b1*np.random.sample(10000)
c1 = -12*mu_c1 + 2*sigma_c1*np.random.sample(10000)
x01 = (-b1 - np.sqrt(b1**2 - (4*a1*c1)))/(2*a1)
#####_____#####
#####Creating Subplots#####
fig = plt.figure()
plt.subplots_adjust(left=0.13,right=0.99,bottom=0.05)
ax1 = fig.add_subplot(331) #Subplot 1
ax1.set_xlabel('a' , fontsize = 14)
ax1.grid(True)
ax2 = fig.add_subplot(334) #Subplot 2
ax2.set_xlabel('b', fontsize = 14)
ax2.grid(True)
ax3 = fig.add_subplot(337) #Subplot 3
ax3.set_xlabel('c', fontsize = 14)
ax3.grid(True)
ax4 = fig.add_subplot(132) #Subplot 4
ax4.set_xlabel('x0', fontsize = 14)
ax4.set_ylabel('PDF', fontsize = 14)
ax4.grid(True)
ax5 = fig.add_subplot(133) #Subplot 5
ax5.set_xlabel('x0', fontsize = 14)
ax5.set_ylabel('CDF', fontsize = 14)
ax5.grid(True)
#####_____#####
#####Plotting Distributions#####
[n1,bins1,patches] = ax1.hist(a1, bins=50, color = 'red',alpha = 0.5, normed = True)
[n2,bins2,patches] = ax2.hist(b1, bins=50, color = 'red',alpha = 0.5, normed = True)
[n3,bins3,patches] = ax3.hist(c1, bins=50, color = 'red',alpha = 0.5, normed = True)
[n4,bins4,patches] = ax4.hist(x01, bins=50, color = 'red',alpha = 0.5, normed = True)
ax4.axvline(np.mean(x01), color = 'black', linestyle = 'dashed', lw = 2)
dx = bins4[1] - bins4[0]
CDF = np.cumsum(n4)*dx
ax5.plot(bins4[1:], CDF, color = 'red')
#####_____#####
#####Event handler for button_press_event#####
def enter_axes(event):
print('enter_axes', event.inaxes)
event.canvas.draw()
def leave_axes(event):
print('leave_axes', event.inaxes)
event.canvas.draw()
def onclick(event):
'''
Event handler for button_press_event
@param event MouseEvent
'''
global ix
ix = event.xdata
if ix is not None:
print 'x = %f' %(ix)
ax4.clear()
ax5.clear()
ax4.grid(True)
ax5.grid(True)
[n4,bins4,patches] = ax4.hist(x01, bins=50, color = 'red',alpha = 0.5, normed = True)
ax4.axvline(np.mean(x01), color = 'black', linestyle = 'dashed', lw = 2)
xmin = ix
xmax = ax4.get_xlim()[1]
ax4.axvspan(xmin, xmax, facecolor='0.9', alpha=0.5)
dx = bins4[1] - bins4[0]
CDF = np.cumsum(n4)*dx
ax5.plot(bins4[1:], CDF, color = 'red')
ax5.axvspan(xmin, xmax, facecolor='0.9', alpha=0.5)
plt.draw()
return ix
cid = fig.canvas.mpl_connect('button_press_event', onclick)
#fig.canvas.mpl_disconnect(cid)
plt.show()
#####_____#####
Thanks in advance :-) 提前致谢 :-)
You can use the inaxes
property of event
to find which axes you are in. See the docs here . 您可以使用event
的inaxes
属性来查找您所在的轴。请参阅此处的文档 。 If you iterate through your subplot Axes
, you can then compare the result of inaxes
to each Axes
instance, and then only go ahead with drawing the shaded region if you are in ax4
or ax5
. 如果遍历子图Axes
,则可以将inaxes
的结果与每个Axes
实例进行比较,然后如果您在ax4
或ax5
,则仅继续绘制阴影区域。
I've modified your onclick
function to do that. 我已经修改了你的onclick
功能来做到这一点。 For information, it also prints which axes the click was in, but you can turn that off once you satisfy yourself that it is working as planned. 有关信息,它还会打印点击所在的轴,但是一旦您确信它按计划运行,您就可以将其关闭。
def onclick(event):
'''
Event handler for button_press_event
@param event MouseEvent
'''
global ix
ix = event.xdata
for i, ax in enumerate([ax1, ax2, ax3, ax4, ax5]):
# For infomation, print which axes the click was in
if ax == event.inaxes:
print "Click is in axes ax{}".format(i+1)
# Check if the click was in ax4 or ax5
if event.inaxes in [ax4, ax5]:
if ix is not None:
print 'x = %f' %(ix)
ax4.clear()
ax5.clear()
ax4.grid(True)
ax5.grid(True)
[n4,bins4,patches] = ax4.hist(x01, bins=50, color = 'red',alpha = 0.5, normed = True)
ax4.axvline(np.mean(x01), color = 'black', linestyle = 'dashed', lw = 2)
xmin = ix
xmax = ax4.get_xlim()[1]
ax4.axvspan(xmin, xmax, facecolor='0.9', alpha=0.5)
dx = bins4[1] - bins4[0]
CDF = np.cumsum(n4)*dx
ax5.plot(bins4[1:], CDF, color = 'red')
ax5.axvspan(xmin, xmax, facecolor='0.9', alpha=0.5)
plt.draw()
return ix
else:
return
Note: I took inspiration for this answer from this other SO answer . 注意:我从其他SO答案中获得了这个答案的灵感。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.