使用matplotlib和twinx进行光标跟踪 [英] cursor tracking using matplotlib and twinx
问题描述
我想同时跟踪鼠标在两个轴上相对于数据坐标的坐标.我可以很好地跟踪鼠标相对于一个轴的位置. 问题是::当我添加带有twinx()
的第二个轴时,两个Cursors
报告数据坐标仅相对于 second 轴.
I would like to track the coordinates of the mouse with respect to data coordinates on two axes simultaneously. I can track the mouse position with respect to one axis just fine. The problem is: when I add a second axis with twinx()
, both Cursors
report data coordinates with respect to the second axis only.
例如,我的游标(fern
和muffy
)报告y
值为7.93
For example, my Cursors (fern
and muffy
) report the y
-value is 7.93
Fern: (1597.63, 7.93)
Muffy: (1597.63, 7.93)
如果我使用:
inv = ax.transData.inverted()
x, y = inv.transform((event.x, event.y))
我收到一个IndexError.
I get an IndexError.
所以问题是:如何修改代码以跟踪相对于两个轴的数据坐标?
So the question is: How can I modify the code to track the data coordinates with respect to both axes?
import numpy as np
import matplotlib.pyplot as plt
import logging
logger = logging.getLogger(__name__)
class Cursor(object):
def __init__(self, ax, name):
self.ax = ax
self.name = name
plt.connect('motion_notify_event', self)
def __call__(self, event):
x, y = event.xdata, event.ydata
ax = self.ax
# inv = ax.transData.inverted()
# x, y = inv.transform((event.x, event.y))
logger.debug('{n}: ({x:0.2f}, {y:0.2f})'.format(n=self.name,x=x,y=y))
logging.basicConfig(level=logging.DEBUG,
format='%(message)s',)
fig, ax = plt.subplots()
x = np.linspace(1000, 2000, 500)
y = 100*np.sin(20*np.pi*(x-1500)/2000.0)
fern = Cursor(ax, 'Fern')
ax.plot(x,y)
ax2 = ax.twinx()
z = x/200.0
muffy = Cursor(ax2, 'Muffy')
ax2.semilogy(x,z)
plt.show()
推荐答案
由于回叫工作的方式,该事件始终在上轴返回.您只需要一点逻辑即可检查事件是否在我们想要的轴上发生:
Due to the way that the call backs work, the event always returns in the top axes. You just need a bit of logic to check which if the event happens in the axes we want:
class Cursor(object):
def __init__(self, ax, x, y, name):
self.ax = ax
self.name = name
plt.connect('motion_notify_event', self)
def __call__(self, event):
if event.inaxes is None:
return
ax = self.ax
if ax != event.inaxes:
inv = ax.transData.inverted()
x, y = inv.transform(np.array((event.x, event.y)).reshape(1, 2)).ravel()
elif ax == event.inaxes:
x, y = event.xdata, event.ydata
else:
return
logger.debug('{n}: ({x:0.2f}, {y:0.2f})'.format(n=self.name,x=x,y=y))
这可能是转换堆栈中的一个细微错误(或者这是正确的用法,很幸运,它以前曾与tuple一起工作过),但是无论如何,这将使其起作用.问题在于,transform.py
中第1996行的代码希望返回2D ndarray
,但是身份转换只是返回传递到其中的元组,这就是产生错误的原因.
This might be a subtle bug down in the transform stack (or this is the correct usage and it was by luck it worked with tuples before), but at any rate, this will make it work. The issue is that the code at line 1996 in transform.py
expects to get a 2D ndarray
back, but the identity transform just returns the tuple that get handed into it, which is what generates the errors.
这篇关于使用matplotlib和twinx进行光标跟踪的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!