使用matplotlib和twinx进行光标跟踪 [英] cursor tracking using matplotlib and twinx

查看:138
本文介绍了使用matplotlib和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.

例如,我的游标(fernmuffy)报告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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆