Интерактивный зум с автомасштабированием оси Y - PullRequest
0 голосов
/ 15 ноября 2018

Я пытаюсь изменить поведение интерактивного масштабирования в прямоугольник, чтобы данные автоматически масштабировались по оси y на основе нового видимого диапазона оси x. Действительно, я изучаю много телеметрических данных с большой динамикой, и мне нужно многократно изменять масштаб изображения. Так что было бы хорошо иметь автоматическое масштабирование оси Y. После долгих поисков по форуму я не нашел ничего, что помогло бы достичь этого. Или, может быть, я неправильно искал. Может ли кто-нибудь дать мне руководство?

1 Ответ

0 голосов
/ 16 ноября 2018

Один из вариантов - подключиться к сигналу xlim_changed и рассчитать, основываясь на текущих пределах x, новые пределы для оси y так, чтобы все данные были включены.

Следующее делает это, и это немного сложнее, чем первоначально предполагалось, потому что просто установка пределов y не сработает, потому что они будут перезаписаны (одновременным) событием ylim_changed, которое вызывает масштабирование. Таким образом, вместо этого есть таймер, установленный на 10 миллисекунд, который искусственно устанавливает пределы после обработки этого события.

import numpy as np; np.random.seed(42)
import matplotlib.pyplot as plt

class AutoScaleY():
    def  __init__(self, line, margin=0.05):
        self.margin = margin
        self.line = line
        self.ax = line.axes
        self.ax.callbacks.connect('xlim_changed', self.rescale_y)

    def rescale_y(self,evt=None):
        xmin, xmax = ax.get_xlim()
        x, y = line.get_data()
        cond = (x >= xmin) & (x <= xmax)
        yrest = y[cond]
        margin = (yrest.max()-yrest.min())*self.margin
        self.ybounds = [yrest.min()-margin, yrest.max()+margin]
        self.timer = self.ax.figure.canvas.new_timer(interval=10)
        self.timer.single_shot = True
        self.timer.add_callback(self.change_y)
        self.timer.start()

    def change_y(self):
        self.ax.set_ylim(self.ybounds)
        self.ax.figure.canvas.draw()


x=np.linspace(0,100,1001)
y = np.sin(x/16) + np.cumsum(np.random.randn(1001))/30.

fig, ax = plt.subplots()
line, = ax.plot(x,y)
r = AutoScaleY(line)

plt.show()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...