Сводка об ошибках
Масштабирование и панорамирование работают должным образом (быстро), если на рисунке присутствуют только линии или маркеры, после добавления ax.text или ax.annotate это становится очень медленный. Я намерен использовать этот код как минимум для 3000 текста и 1000 строк и перемещаться по холсту в GUI (PySimple GUI). Мой опыт программирования невелик, поэтому может быть так, как написан класс, что и является причиной этого. Фрагмент кода является минимальным примером проблемы.
Код для воспроизведения
class _Zoom_Pan_():
def __init__(self, fig, ax1, base_scale):
'Declarar variables'
self.fig, self.ax1, self.base_scale, self.x_init, self.y_init, = fig, ax1, base_scale, None, None
"Conectar funcion"
self._add_connection("button_press_event", self._OnPress_)
self._add_connection("motion_notify_event", self._OnMotion_)
self._add_connection("button_release_event", self._OffPress_)
self._add_connection("scroll_event", self._Zoom_)
def _add_connection(self, event_name, callback):
self.fig.canvas.mpl_connect(event_name, callback)
def Canvas_Draw(self):
self.fig.canvas.draw_idle()
def _OnPress_(self, event):
if event.xdata != None and event.button == 2:
self. x_init, self.y_init = event.xdata, event.ydata
def _OnMotion_(self, event):
if self.x_init != None and event.xdata != None:
xmin, xmax, ymin, ymax = self.ax1.axis()
dx, dy = self.x_init - event.xdata, self.y_init - event.ydata
self.ax1.set(xlim=(xmin + dx, xmax + dx), ylim=(ymin + dy, ymax + dy))
self.Canvas_Draw()
def _OffPress_(self, event):
self.x_init = None
def _Zoom_(self, event):
if event.step:
'Obtener limites de ax1'
xmin, xmax, ymin, ymax = self.ax1.axis()
xdata, ydata = event.xdata, event.ydata
'Obtener factor de escala'
if event.step < 0:
scale_factor = 1 / self.base_scale
if event.step > 0:
scale_factor = self.base_scale
'Asignar nuevos limites'
xmin_new, xmax_new = xdata - (xdata - xmin) / scale_factor, xdata + (xmax - xdata) / scale_factor
ymin_new, ymax_new = ydata - (ydata - ymin) / scale_factor, ydata + (ymax - ydata) / scale_factor
self.ax1.set(xlim=(xmin_new, xmax_new), ylim=(ymin_new, ymax_new))
self.Canvas_Draw()
import matplotlib.pyplot as plt
import numpy as np
"Create data"
count = 1000
data = np.random.rand(1, count)[0]
"plot data"
fig = plt.figure()
ax1 = fig.add_subplot(111, rasterized=True)
for i in range(len(data) - 1):
ax1.plot([i, i + 1], [data[i], data[i + 1]], rasterized=True, gid='Line' + str(i))
ax1.annotate('Text', xy=(np.asarray([i, i + 1]).mean(),
np.asarray([data[i], data[i + 1]]).mean()),
xytext=(np.asarray([i, i + 1]).mean(),
np.asarray([data[i], data[i + 1]]).mean()),
arrowprops=dict(arrowstyle="->", color='red'),
rasterized=True,
gid='arrow_' + str(i))
"Apply zoom and pan"
Mpl_func = _Zoom_Pan_(fig, ax1, 2.5)
"Show figure"
plt.show()
Фактический результат
Медленное панорамирование и масштабирование
Ожидаемый результат
Быстрое панорамирование и масштабирование
Версия Matplotlib
- Эксплуатация система: Windows
- Версия Matplotlib: 3.1.1
- Бэкэнд Matplotlib: TkAgg
- Python Версия: 3.7
- Другие библиотеки: Использование этого код внутри PySiple GUI Canvas