使用 matplotlib 在单击时绘制点的问题
Problem with plotting a dot on click with matplotlib
我刚开始学习python和交互式绘图,欢迎任何帮助。
这段代码的目的是点击十个按钮之一来选择-5到5之间的一个值,然后通过点击主轴上的任意位置显示这个值,然后从这些点生成电场图.问题是,当我单击任何按钮时,图形中间会绘制一个点。
如果我正确理解发生了什么,onclick 函数会将每个按钮的轴解释为主轴的一部分。
有人可以帮我解决这个问题吗?
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.widgets import Button
fig, ax= plt.subplots(figsize=(8,8))
axButton1=plt.axes([0,0.90,0.1,0.07])
btn1= Button(axButton1,label='-5')
axButton2=plt.axes([0.1,0.90,0.1,0.07])
btn2= Button(axButton2,label='-4')
axButton3=plt.axes([0.2,0.90,0.1,0.07])
btn3= Button(axButton3,label='-3')
axButton4=plt.axes([0.3,0.90,0.1,0.07])
btn4= Button(axButton4,label='-2')
axButton5=plt.axes([0.4,0.90,0.1,0.07])
btn5= Button(axButton5,label='-1')
axButton6=plt.axes([0.5,0.90,0.1,0.07])
btn6= Button(axButton6,label='1')
axButton7=plt.axes([0.6,0.90,0.1,0.07])
btn7= Button(axButton7,label='2')
axButton8=plt.axes([0.7,0.90,0.1,0.07])
btn8= Button(axButton8,label='3')
axButton9=plt.axes([0.8,0.90,0.1,0.07])
btn9= Button(axButton9,label='4')
axButton10=plt.axes([0.9,0.90,0.1,0.07])
btn10= Button(axButton10,label='5')
q=0
def neg5(event):
global q
q=-5
btn1.on_clicked(neg5)
def neg4(event):
global q
q=-4
btn2.on_clicked(neg4)
def neg3(event):
global q
q=-3
btn3.on_clicked(neg3)
def neg2(event):
global q
q=-2
btn4.on_clicked(neg2)
def neg1(event):
global q
q=-1
btn5.on_clicked(neg1)
def pos1(event):
global q
q=1
btn6.on_clicked(pos1)
def pos2(event):
global q
q=2
btn7.on_clicked(pos2)
def pos3(event):
global q
q=3
btn8.on_clicked(pos3)
def pos4(event):
global q
q=4
btn9.on_clicked(pos4)
def pos5(event):
global q
q=5
btn10.on_clicked(pos5)
plt.subplots_adjust(top=0.77, bottom=0.05)
ax.set_xlim([-5, 5])
ax.set_ylim([-5, 5])
charges=[]
def onclick(event):
global charges
M=(event.xdata, event.ydata)
print('button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %
(event.button, event.x, event.y, event.xdata, event.ydata))
charges.append(M)
print(charges)
ax.add_artist(mpl.patches.Circle(M, 0.3, color='r', ec='black', lw=1.5))
ax.text(event.xdata,event.ydata,str(q), size='20', color='w', zorder=2, horizontalalignment = 'center', verticalalignment = 'center')
fig.canvas.draw()
cid = fig.canvas.mpl_connect('button_press_event', onclick)
plt.show()
欢迎,欢迎来到 Python。
我确定我没有最佳答案,因为我没有使用过 canvas.mpl_connect,但我相信我有一个适合您的解决方案。
将所有 onclick(events)
放在 if 语句下,这样单击按钮(子图,而不是主坐标轴)就不会触发所有内容:
def onclick(event):
if issubclass(event.inaxes.__class__, mpl.axes.SubplotBase):
global charges
M=(event.xdata, event.ydata)
print('button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %
(event.button, event.x, event.y, event.xdata, event.ydata))
charges.append(M)
print(charges)
ax.add_artist( mpl.patches.Circle(M, 0.3, color='r', ec='black', lw=1.5) )
ax.text(event.xdata,event.ydata,str(q), size='20', color='w', zorder=2, horizontalalignment = 'center', verticalalignment = 'center')
fig.canvas.draw()
您可以使用 event.inaxes
检查事件的来源。
这是一个示例实现。我还使用工厂清理了 q
setter 函数。类似的东西也适用于按钮的创建,然后你可以在循环中做所有事情而不需要太多重复。我鼓励你尝试一下。
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.widgets import Button
fig, ax= plt.subplots(figsize=(8,8))
axButton1=plt.axes([0,0.90,0.1,0.07])
btn1= Button(axButton1,label='-5')
axButton2=plt.axes([0.1,0.90,0.1,0.07])
btn2= Button(axButton2,label='-4')
axButton3=plt.axes([0.2,0.90,0.1,0.07])
btn3= Button(axButton3,label='-3')
axButton4=plt.axes([0.3,0.90,0.1,0.07])
btn4= Button(axButton4,label='-2')
axButton5=plt.axes([0.4,0.90,0.1,0.07])
btn5= Button(axButton5,label='-1')
axButton6=plt.axes([0.5,0.90,0.1,0.07])
btn6= Button(axButton6,label='1')
axButton7=plt.axes([0.6,0.90,0.1,0.07])
btn7= Button(axButton7,label='2')
axButton8=plt.axes([0.7,0.90,0.1,0.07])
btn8= Button(axButton8,label='3')
axButton9=plt.axes([0.8,0.90,0.1,0.07])
btn9= Button(axButton9,label='4')
axButton10=plt.axes([0.9,0.90,0.1,0.07])
btn10= Button(axButton10,label='5')
q=0
#generator function for q setters
def valueSetterFuncGen(val):
def func(event):
global q
q = val
return func
btn1.on_clicked(valueSetterFuncGen(-5))
btn2.on_clicked(valueSetterFuncGen(-4))
btn3.on_clicked(valueSetterFuncGen(-3))
btn4.on_clicked(valueSetterFuncGen(-2))
btn5.on_clicked(valueSetterFuncGen(-1))
btn6.on_clicked(valueSetterFuncGen(1))
btn7.on_clicked(valueSetterFuncGen(2))
btn8.on_clicked(valueSetterFuncGen(3))
btn9.on_clicked(valueSetterFuncGen(4))
btn10.on_clicked(valueSetterFuncGen(5))
plt.subplots_adjust(top=0.77, bottom=0.05)
ax.set_xlim([-5, 5])
ax.set_ylim([-5, 5])
charges=[]
def onclick(event):
if event.inaxes==ax:
global charges
M=(event.xdata, event.ydata)
print('button=%d, x=%d, y=%d, xdata=%f, ydata=%f, ax = %s' %
(event.button, event.x, event.y, event.xdata, event.ydata, event.inaxes==ax))
charges.append(M)
print(charges)
ax.add_artist(mpl.patches.Circle(M, 0.3, color='r', ec='black', lw=1.5))
ax.text(event.xdata,event.ydata,str(q), size='20', color='w', zorder=2, horizontalalignment = 'center', verticalalignment = 'center')
fig.canvas.draw()
cid = fig.canvas.mpl_connect('button_press_event', onclick)
plt.show()
---剧透---
这是解决方案
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.widgets import Button
fig, ax= plt.subplots(figsize=(8,8))
#factory function for q setters
def valueSetterFuncGen(val):
def func(event):
global q
q = val
return func
btns = []
for i in range(10):
axButton_=plt.axes([i/10.,0.90,0.1,0.07])
l = ''
if i-5 < 0:
l = int(i-5)
else:
l = int(i-4)
# if we are already looping, a button factory would not make things easier
btn_= Button(axButton_,label=str(l))
btn_.on_clicked(valueSetterFuncGen(l))
btns.append(btn_)
plt.subplots_adjust(top=0.77, bottom=0.05)
ax.set_xlim([-5, 5])
ax.set_ylim([-5, 5])
q=0
charges=[]
def onclick(event):
if event.inaxes==ax:
global charges
M=(event.xdata, event.ydata)
print('button=%d, x=%d, y=%d, xdata=%f, ydata=%f, ax = %s' %
(event.button, event.x, event.y, event.xdata, event.ydata, event.inaxes==ax))
charges.append(M)
print(charges)
ax.add_artist(mpl.patches.Circle(M, 0.3, color='r', ec='black', lw=1.5))
ax.text(event.xdata,event.ydata,str(q), size='20', color='w', zorder=2, horizontalalignment = 'center', verticalalignment = 'center')
fig.canvas.draw()
cid = fig.canvas.mpl_connect('button_press_event', onclick)
plt.show()
我刚开始学习python和交互式绘图,欢迎任何帮助。
这段代码的目的是点击十个按钮之一来选择-5到5之间的一个值,然后通过点击主轴上的任意位置显示这个值,然后从这些点生成电场图.问题是,当我单击任何按钮时,图形中间会绘制一个点。 如果我正确理解发生了什么,onclick 函数会将每个按钮的轴解释为主轴的一部分。 有人可以帮我解决这个问题吗?
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.widgets import Button
fig, ax= plt.subplots(figsize=(8,8))
axButton1=plt.axes([0,0.90,0.1,0.07])
btn1= Button(axButton1,label='-5')
axButton2=plt.axes([0.1,0.90,0.1,0.07])
btn2= Button(axButton2,label='-4')
axButton3=plt.axes([0.2,0.90,0.1,0.07])
btn3= Button(axButton3,label='-3')
axButton4=plt.axes([0.3,0.90,0.1,0.07])
btn4= Button(axButton4,label='-2')
axButton5=plt.axes([0.4,0.90,0.1,0.07])
btn5= Button(axButton5,label='-1')
axButton6=plt.axes([0.5,0.90,0.1,0.07])
btn6= Button(axButton6,label='1')
axButton7=plt.axes([0.6,0.90,0.1,0.07])
btn7= Button(axButton7,label='2')
axButton8=plt.axes([0.7,0.90,0.1,0.07])
btn8= Button(axButton8,label='3')
axButton9=plt.axes([0.8,0.90,0.1,0.07])
btn9= Button(axButton9,label='4')
axButton10=plt.axes([0.9,0.90,0.1,0.07])
btn10= Button(axButton10,label='5')
q=0
def neg5(event):
global q
q=-5
btn1.on_clicked(neg5)
def neg4(event):
global q
q=-4
btn2.on_clicked(neg4)
def neg3(event):
global q
q=-3
btn3.on_clicked(neg3)
def neg2(event):
global q
q=-2
btn4.on_clicked(neg2)
def neg1(event):
global q
q=-1
btn5.on_clicked(neg1)
def pos1(event):
global q
q=1
btn6.on_clicked(pos1)
def pos2(event):
global q
q=2
btn7.on_clicked(pos2)
def pos3(event):
global q
q=3
btn8.on_clicked(pos3)
def pos4(event):
global q
q=4
btn9.on_clicked(pos4)
def pos5(event):
global q
q=5
btn10.on_clicked(pos5)
plt.subplots_adjust(top=0.77, bottom=0.05)
ax.set_xlim([-5, 5])
ax.set_ylim([-5, 5])
charges=[]
def onclick(event):
global charges
M=(event.xdata, event.ydata)
print('button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %
(event.button, event.x, event.y, event.xdata, event.ydata))
charges.append(M)
print(charges)
ax.add_artist(mpl.patches.Circle(M, 0.3, color='r', ec='black', lw=1.5))
ax.text(event.xdata,event.ydata,str(q), size='20', color='w', zorder=2, horizontalalignment = 'center', verticalalignment = 'center')
fig.canvas.draw()
cid = fig.canvas.mpl_connect('button_press_event', onclick)
plt.show()
欢迎,欢迎来到 Python。
我确定我没有最佳答案,因为我没有使用过 canvas.mpl_connect,但我相信我有一个适合您的解决方案。
将所有 onclick(events)
放在 if 语句下,这样单击按钮(子图,而不是主坐标轴)就不会触发所有内容:
def onclick(event):
if issubclass(event.inaxes.__class__, mpl.axes.SubplotBase):
global charges
M=(event.xdata, event.ydata)
print('button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %
(event.button, event.x, event.y, event.xdata, event.ydata))
charges.append(M)
print(charges)
ax.add_artist( mpl.patches.Circle(M, 0.3, color='r', ec='black', lw=1.5) )
ax.text(event.xdata,event.ydata,str(q), size='20', color='w', zorder=2, horizontalalignment = 'center', verticalalignment = 'center')
fig.canvas.draw()
您可以使用 event.inaxes
检查事件的来源。
这是一个示例实现。我还使用工厂清理了 q
setter 函数。类似的东西也适用于按钮的创建,然后你可以在循环中做所有事情而不需要太多重复。我鼓励你尝试一下。
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.widgets import Button
fig, ax= plt.subplots(figsize=(8,8))
axButton1=plt.axes([0,0.90,0.1,0.07])
btn1= Button(axButton1,label='-5')
axButton2=plt.axes([0.1,0.90,0.1,0.07])
btn2= Button(axButton2,label='-4')
axButton3=plt.axes([0.2,0.90,0.1,0.07])
btn3= Button(axButton3,label='-3')
axButton4=plt.axes([0.3,0.90,0.1,0.07])
btn4= Button(axButton4,label='-2')
axButton5=plt.axes([0.4,0.90,0.1,0.07])
btn5= Button(axButton5,label='-1')
axButton6=plt.axes([0.5,0.90,0.1,0.07])
btn6= Button(axButton6,label='1')
axButton7=plt.axes([0.6,0.90,0.1,0.07])
btn7= Button(axButton7,label='2')
axButton8=plt.axes([0.7,0.90,0.1,0.07])
btn8= Button(axButton8,label='3')
axButton9=plt.axes([0.8,0.90,0.1,0.07])
btn9= Button(axButton9,label='4')
axButton10=plt.axes([0.9,0.90,0.1,0.07])
btn10= Button(axButton10,label='5')
q=0
#generator function for q setters
def valueSetterFuncGen(val):
def func(event):
global q
q = val
return func
btn1.on_clicked(valueSetterFuncGen(-5))
btn2.on_clicked(valueSetterFuncGen(-4))
btn3.on_clicked(valueSetterFuncGen(-3))
btn4.on_clicked(valueSetterFuncGen(-2))
btn5.on_clicked(valueSetterFuncGen(-1))
btn6.on_clicked(valueSetterFuncGen(1))
btn7.on_clicked(valueSetterFuncGen(2))
btn8.on_clicked(valueSetterFuncGen(3))
btn9.on_clicked(valueSetterFuncGen(4))
btn10.on_clicked(valueSetterFuncGen(5))
plt.subplots_adjust(top=0.77, bottom=0.05)
ax.set_xlim([-5, 5])
ax.set_ylim([-5, 5])
charges=[]
def onclick(event):
if event.inaxes==ax:
global charges
M=(event.xdata, event.ydata)
print('button=%d, x=%d, y=%d, xdata=%f, ydata=%f, ax = %s' %
(event.button, event.x, event.y, event.xdata, event.ydata, event.inaxes==ax))
charges.append(M)
print(charges)
ax.add_artist(mpl.patches.Circle(M, 0.3, color='r', ec='black', lw=1.5))
ax.text(event.xdata,event.ydata,str(q), size='20', color='w', zorder=2, horizontalalignment = 'center', verticalalignment = 'center')
fig.canvas.draw()
cid = fig.canvas.mpl_connect('button_press_event', onclick)
plt.show()
---剧透---
这是解决方案
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.widgets import Button
fig, ax= plt.subplots(figsize=(8,8))
#factory function for q setters
def valueSetterFuncGen(val):
def func(event):
global q
q = val
return func
btns = []
for i in range(10):
axButton_=plt.axes([i/10.,0.90,0.1,0.07])
l = ''
if i-5 < 0:
l = int(i-5)
else:
l = int(i-4)
# if we are already looping, a button factory would not make things easier
btn_= Button(axButton_,label=str(l))
btn_.on_clicked(valueSetterFuncGen(l))
btns.append(btn_)
plt.subplots_adjust(top=0.77, bottom=0.05)
ax.set_xlim([-5, 5])
ax.set_ylim([-5, 5])
q=0
charges=[]
def onclick(event):
if event.inaxes==ax:
global charges
M=(event.xdata, event.ydata)
print('button=%d, x=%d, y=%d, xdata=%f, ydata=%f, ax = %s' %
(event.button, event.x, event.y, event.xdata, event.ydata, event.inaxes==ax))
charges.append(M)
print(charges)
ax.add_artist(mpl.patches.Circle(M, 0.3, color='r', ec='black', lw=1.5))
ax.text(event.xdata,event.ydata,str(q), size='20', color='w', zorder=2, horizontalalignment = 'center', verticalalignment = 'center')
fig.canvas.draw()
cid = fig.canvas.mpl_connect('button_press_event', onclick)
plt.show()