Взаимодействующая визуализация данных с использованием Matplotlib

Beginner

This tutorial is from open-source community. Access the source code

Введение

В визуализации данных приближение к определенной области графика может быть чрезвычайно полезным для лучшего понимания и анализа данных. Matplotlib, популярная библиотека визуализации данных для Python, предоставляет способ создать два идентичных панели и приблизиться к правой панели, чтобы показать прямоугольник на первой панели, обозначающий зуммированную область. В этом практическом занятии мы научимся создавать эту интерактивную функцию приближения в Matplotlib.

Советы по работе с ВМ

После запуска ВМ кликните в левом верхнем углу, чтобы переключиться на вкладку Notebook и получить доступ к Jupyter Notebook для практики.

Иногда вам может потребоваться подождать несколько секунд, пока Jupyter Notebook не загрузится полностью. Валидация операций не может быть автоматизирована из-за ограничений Jupyter Notebook.

Если вы сталкиваетесь с проблемами во время обучения, не стесняйтесь обращаться к Labby. Оставьте отзыв после занятия, и мы оперативно решим проблему для вас.

Импортируем необходимые библиотеки

Сначала мы импортируем необходимые библиотеки, в том числе Matplotlib и NumPy.

import matplotlib.pyplot as plt
import numpy as np

from matplotlib.patches import Rectangle

Создаем класс UpdatingRect

Мы создадим подкласс Rectangle под названием UpdatingRect. Этот класс вызывается с экземпляром Axes, заставляя прямоугольник обновить свою форму, чтобы соответствовать границам Axes.

class UpdatingRect(Rectangle):
    def __call__(self, ax):
        self.set_bounds(*ax.viewLim.bounds)
        ax.figure.canvas.draw_idle()

Создаем класс MandelbrotDisplay

Мы создадим класс под названием MandelbrotDisplay, который будет перегенерировать фрактальное множество при приближении, чтобы мы могли на самом деле увидеть увеличивающуюся деталь. Коробка на левой панели покажет область, на которую мы приближаемся.

class MandelbrotDisplay:
    def __init__(self, h=500, w=500, niter=50, radius=2., power=2):
        self.height = h
        self.width = w
        self.niter = niter
        self.radius = radius
        self.power = power

    def compute_image(self, xstart, xend, ystart, yend):
        self.x = np.linspace(xstart, xend, self.width)
        self.y = np.linspace(ystart, yend, self.height).reshape(-1, 1)
        c = self.x + 1.0j * self.y
        threshold_time = np.zeros((self.height, self.width))
        z = np.zeros(threshold_time.shape, dtype=complex)
        mask = np.ones(threshold_time.shape, dtype=bool)
        for i in range(self.niter):
            z[mask] = z[mask]**self.power + c[mask]
            mask = (np.abs(z) < self.radius)
            threshold_time += mask
        return threshold_time

    def ax_update(self, ax):
        ax.set_autoscale_on(False)
        self.width, self.height = \
            np.round(ax.patch.get_window_extent().size).astype(int)
        vl = ax.viewLim
        extent = vl.x0, vl.x1, vl.y0, vl.y1
        im = ax.images[-1]
        im.set_data(self.compute_image(*extent))
        im.set_extent(extent)
        ax.figure.canvas.draw_idle()

Создаем график

Мы создадим график, сначала вычислив изображение с использованием класса MandelbrotDisplay, а затем создав две идентичные панели с использованием subplots. Мы добавим изображение на обе панели с использованием imshow и добавим объект UpdatingRect на левую панель.

md = MandelbrotDisplay()
Z = md.compute_image(-2., 0.5, -1.25, 1.25)

fig1, (ax1, ax2) = plt.subplots(1, 2)
ax1.imshow(Z, origin='lower',
           extent=(md.x.min(), md.x.max(), md.y.min(), md.y.max()))
ax2.imshow(Z, origin='lower',
           extent=(md.x.min(), md.x.max(), md.y.min(), md.y.max()))

rect = UpdatingRect(
    [0, 0], 0, 0, facecolor='none', edgecolor='black', linewidth=1.0)
rect.set_bounds(*ax2.viewLim.bounds)
ax1.add_patch(rect)

Добавляем функциональность приближения

Мы добавим функциональность приближения, подключив события xlim_changed и ylim_changed к объектам UpdatingRect и MandelbrotDisplay.

ax2.callbacks.connect('xlim_changed', rect)
ax2.callbacks.connect('ylim_changed', rect)

ax2.callbacks.connect('xlim_changed', md.ax_update)
ax2.callbacks.connect('ylim_changed', md.ax_update)
ax2.set_title("Zoom here")

Показываем график

Мы покажем график с использованием функции show().

plt.show()

Резюме

В этом практическом занятии мы узнали, как создать интерактивную функцию приближения в Matplotlib с использованием двух идентичных панелей и классов UpdatingRect и MandelbrotDisplay. Добавив функциональность приближения, мы можем лучше понять и проанализировать данные в наших графиках.