Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
304 views
in Technique[技术] by (71.8m points)

python - Annotation of the first axes does not show when adding the second axes into Matplotlib Figure

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.widgets import Button

y = np.random.randint(1, 100, size=50)
y2 = np.random.randint(1, 100, size=50)
fig = plt.figure()
ax = fig.add_subplot(111)


dots1, = ax.plot(y, 'r.', picker=True, label='data1')

ax2 = ax.twinx()#Comment out the second axes, the annotation works.
dots2, = ax2.plot(y2, 'g.', picker=True, label='data2')

fig.legend()
anno = ax.annotate('N/A', xy=(0, 0), xytext=(-250, 25),
                   textcoords=('offset pixels'),
                   bbox=dict(boxstyle='round', fc='w', alpha=1),
                   arrowprops=dict(arrowstyle='fancy')
)

anno.set_visible(False)

def motion(event):
    x = event.xdata
    y = event.ydata
    v = anno.get_visible()
    if event.inaxes == ax:
        c1, ind1 = dots1.contains(event)
        c2, ind2 = dots2.contains(event)


        if c1 or c2:
            anno.xy = (x, y)
            anno.set_text(f'{x}-{y}')
            anno.set_visible(True)
    if v:
        anno.set_visible(False)
    event.canvas.draw_idle()

fig.canvas.mpl_connect('motion_notify_event', motion)
plt.show()

Hi, I am trying to plot two sets of Y values onto two axes. When there is only one axis, 'ax' in the code above, the annotation shows and works properly, but once the second axis is added into the graph, 'ax2' in the code, the annotation does not work anymore.

I tried to debug this and found out that every time 'motion' is called, the event comes with only ax2, which means 'if event.inaxes == ax' will always be False.

What should I do to make 'motion' function to be notified with both ax and ax2?

Thank you.

question from:https://stackoverflow.com/questions/66057274/annotation-of-the-first-axes-does-not-show-when-adding-the-second-axes-into-matp

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I don't have much experience with this type of graph processing, but I was able to handle the condition for two axes with in (ax, ax2). The other thing I fixed was the parameter for the position of the annotations.

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.widgets import Button

y = np.random.randint(1, 100, size=50)
y2 = np.random.randint(1, 100, size=50)
fig = plt.figure()
ax = fig.add_subplot(111)

ax2 = ax.twinx()#Comment out the second axes, the annotation works.
dots1, = ax.plot(y, 'r.', picker=True, label='data1')
dots2, = ax2.plot(y2, 'g.', picker=True, label='data2')

fig.legend()
anno = ax.annotate('N/A', xy=(0, 0), xytext=(15, 15),# update
                   textcoords=('offset pixels'),
                   bbox=dict(boxstyle='round', fc='w', alpha=1),
                   arrowprops=dict(arrowstyle='fancy')
)

anno.set_visible(False)

def motion(event):
    x = event.xdata
    y = event.ydata
    v = anno.get_visible()
    if event.inaxes in (ax, ax2): # update
        c1, ind1 = dots1.contains(event)
        c2, ind2 = dots2.contains(event)

        if c1 or c2:
            anno.xy = (x, y)
            anno.set_text(f'{x}-{y}')
            anno.set_visible(True)
    if v:
        anno.set_visible(False)
    event.canvas.draw_idle()

fig.canvas.mpl_connect('motion_notify_event', motion)
plt.show()

enter image description here

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...