我想同时跟踪鼠标在两个轴上的数据坐标。我可以跟踪鼠标的位置相对于一个轴只是很好。问题是:当我用twinx()添加第二个轴时,两个Cursors报告的数据坐标都是关于第二个轴的。
例如,我的游标(fern和muffy)报告y-value为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。
所以问题是:我如何修改代码来跟踪两个轴的数据坐标?

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()发布于 2013-05-21 14:48:17
由于回调的工作方式,事件总是在顶部返回。您只需要一点逻辑来检查事件是否发生在我们想要的轴上:
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))这可能是转换堆栈中的一个微妙错误(或者这是正确的用法,幸运的是它以前使用过元组),但无论如何,这将使它工作。问题是,transform.py中第1996行的代码期望得到一个2D ndarray,但是身份转换只返回传递给它的元组,这就是产生错误的原因。
发布于 2014-11-01 23:16:28
您可以使用一个游标(或事件处理程序)这样跟踪两个轴坐标:
import numpy as np
import matplotlib.pyplot as plt
import logging
logger = logging.getLogger(__name__)
class Cursor(object):
def __init__(self):
plt.connect('motion_notify_event', self)
def __call__(self, event):
if event.inaxes is None:
return
x, y1 = ax1.transData.inverted().transform((event.x,event.y))
x, y2 = ax2.transData.inverted().transform((event.x,event.y))
logger.debug('(x,y1,y2)=({x:0.2f}, {y1:0.2f}, {y2:0.2f})'.format(x=x,y1=y1,y2=y2))
logging.basicConfig(level=logging.DEBUG,
format='%(message)s',)
fig, ax1 = plt.subplots()
x = np.linspace(1000, 2000, 500)
y = 100*np.sin(20*np.pi*(x-1500)/2000.0)
fern = Cursor()
ax1.plot(x,y)
ax2 = ax1.twinx()
z = x/200.0
ax2.plot(x,z)
plt.show()(当我像OP一样使用ax2.semilogy(x,z)时,我得到了“太多的索引”,但没有解决这个问题。)
ax1.transData.inverted().transform((event.x,event.y))代码在指定的轴上执行从显示到数据坐标的转换,可以任意与任意轴一起使用。
https://stackoverflow.com/questions/16672530
复制相似问题