matplotlib鼠标悬停在轴之间的注解上

yjghlzjz  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(182)

bounty将在5天后过期。回答此问题可获得+50声望奖励。warped希望吸引更多人关注此问题。

我正在寻找两个子情节之间绘制的注解线。
此时,我正在通过访问引发“motion_notify_event”的ax来重新示例化注解。
最小示例:

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from matplotlib.patches import ConnectionPatch
  4. def update_line_annotation(event, line):
  5. x, y = event.xdata, event.ydata
  6. ax = event.inaxes
  7. global annot # in the real use case, annot is stored as class attribute
  8. annot = ax.annotate(
  9. f'{line}',
  10. xy=(x, y),
  11. xytext=(5, 5),
  12. textcoords='offset points',
  13. )
  14. def hover(event):
  15. annot.set_visible(False)
  16. fig.canvas.draw_idle()
  17. for line in cons:
  18. cont, ind = line.contains(event)
  19. if cont:
  20. update_line_annotation(event, line)
  21. annot.set_visible(True)
  22. break
  23. if __name__ == '__main__':
  24. fig, axes = plt.subplots(ncols=2)
  25. annot = axes[0].annotate(
  26. f'',
  27. xy=(0,0),
  28. xytext=(20, 20),
  29. textcoords='offset points',
  30. )
  31. annot.set_visible(False)
  32. cons = []
  33. for a in range(2):
  34. con = ConnectionPatch(
  35. xyA=np.random.randint(0,10,2),
  36. xyB=np.random.randint(0,10,2),
  37. coordsA='data',
  38. coordsB='data',
  39. axesA=axes[0],
  40. axesB=axes[1],
  41. )
  42. cons.append(con)
  43. axes[1].add_artist(con)
  44. fig.canvas.mpl_connect('motion_notify_event', hover)
  45. for ax in axes:
  46. ax.set_ylim(0,9)
  47. ax.set_xlim(0,9)
  48. plt.show()

我目前的方法有两个问题:

  • 如果光标位于左坐标轴中,则注解绘制在右坐标轴后面。
  • 如果光标在两个轴之间,则会抛出错误,因为event.inaxes返回None,而None没有注解方法。

我有两种可能的解决方案,但我在matplotlib中找不到必要的功能:

  • 相对于右轴进行所有注记。这需要获取相对于该轴的xdata,ydata坐标
  • 生成与ConnectionPatch相关的所有注解

非常感谢您的帮助!

xqkwcwgp

xqkwcwgp1#

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from matplotlib.patches import ConnectionPatch
  4. def hover(event):
  5. for line in cons:
  6. cont, ind = line.contains(event)
  7. if cont:
  8. annot = line.annotate(
  9. f'This is line {line}',
  10. xy=(0.5, 0.5), # Anchor the annotation at the center of the ConnectionPatch
  11. xycoords=line.get_path(), # Use the coordinates of the ConnectionPatch
  12. ha='center',
  13. va='center',
  14. )
  15. annot.set_visible(True)
  16. break
  17. if __name__ == '__main__':
  18. fig, axes = plt.subplots(ncols=2)
  19. cons = []
  20. for a in range(2):
  21. con = ConnectionPatch(
  22. xyA=np.random.randint(0,10,2),
  23. xyB=np.random.randint(0,10,2),
  24. coordsA='data',
  25. coordsB='data',
  26. axesA=axes[0],
  27. axesB=axes[1],
  28. )
  29. cons.append(con)
  30. axes[1].add_artist(con)
  31. fig.canvas.mpl_connect('motion_notify_event', hover)
  32. for ax in axes:
  33. ax.set_ylim(0,9)
  34. ax.set_xlim(0,9)
  35. plt.show()

此代码创建两个子绘图区,然后在它们之间绘制两个ConnectionPatch对象。当鼠标悬停在其中一条线上时,将使用ConnectionPatch的坐标向该线本身添加一个注解。这可以避免您描述的问题,即注解将绘制在其中一个子绘图区的后面,或者event.inaxes将为None

展开查看全部

相关问题