Python Matplotlib自定义缩放函数不起作用

2024-10-06 11:24:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为交互式Mandelbrot集显示制作代码,我希望缩放功能在每次使用时都能更新图像。因此,我使用Matplotlib事件处理来创建自定义缩放函数

放大时,已有的缩放功能将对图像进行像素化,因为它会放大同一图像。我的缩放应该在每次拖动鼠标时更新图像

但它不起作用。每次我缩放一次,绘图不会改变形状,因此图像本身会拉伸。再次缩放,它只会在原始图片上进行缩放。滴答声在整个时间里都不会改变。试试看——这是我的代码和特伦顿·麦金尼提供的图片:

# Get necessary packages
import numpy as np
from matplotlib import pyplot as plt

# Calculation
COLORS = [(1, 0, 0)]
for transition in [[0, 1, 0], [-1, 0, 0], [0, 0, 1], [0, -1, 0], [1, 0, 0]]:
    for _ in range(10):
        r, g, b = COLORS[-1]
        r = round(r + transition[0] / 10, 1)
        g = round(g + transition[1] / 10, 1)
        b = round(b + transition[2] / 10, 1)
        COLORS.append((r, g, b))
        
def color(n):
    z = complex(0, 0)
    c = n
    for n in range(len(COLORS)):
        z = z ** 2 + c
        if abs(z) > 2:
            return COLORS[n]
    return (0, 0, 0)


def get_data(c1, c2):
    d = []
    for i in np.linspace(c1.imag, c2.imag, num = 500):
        rvals = [complex(r, i) for r in np.linspace(c1.real, c2.real, num = 500)]
        d.append(list(map(color, rvals)))
    return d


# Interface
corner1 = (-2, -2)
corner2 = (2, 2)

def display_data(c1, c2):
    data = get_data(c1, c2)
    image.set_data(data)
    figure.show()
    
    
def startzoom(event):
    global corner1, corner2
    if event.button:
        x = event.xdata
        y = event.ydata
        corner1 = corner2 = (x, y)
        
        
def stopzoom(event):
    global corner1, corner2
    if event.button:
        x = event.xdata
        y = event.ydata
        corner2 = (x, y)
        if corner1 == corner2:
            corner1, corner2 = (-2, -2), (2, 2)
        display_data(complex(*corner1), complex(*corner2))
        

# Put it all together
data = get_data(complex(*corner1), complex(*corner2))
figure, axes = plt.subplots()
axes.set_title("Mandelbrot Set")
axes.set_xlabel("Real")
axes.set_ylabel("Imaginary")
image = axes.imshow(list(reversed(data)), extent = [-2, 2, -2, 2])
figure.canvas.mpl_connect("button_press_event", startzoom)
figure.canvas.mpl_connect("button_release_event", stopzoom)
figure.show()

enter image description here

我该怎么办


Tags: in图像eventfordatadeffiguretransition
1条回答
网友
1楼 · 发布于 2024-10-06 11:24:08

我对display_data函数进行了如下编辑:

def display_data(c1, c2):
    data = get_data(c1, c2)
    axes.imshow(list(reversed(data)), extent = [corner1[0], corner2[0], corner1[1], corner2[1]])
    plt.show()

每次用户单击绘图时,应更新extent参数值,以便更新图像边框。
此外,我还添加了axes.invert_xaxis()axes.invert_yaxis()以便在每个方向上都可以进行缩放:从左下到右上、从左上到右下、从右上到左下以及从右下到左上

完整代码

import numpy as np
from matplotlib import pyplot as plt

# Calculation
COLORS = [(1, 0, 0)]
for transition in [[0, 1, 0], [-1, 0, 0], [0, 0, 1], [0, -1, 0], [1, 0, 0]]:
    for _ in range(10):
        r, g, b = COLORS[-1]
        r = round(r + transition[0] / 10, 1)
        g = round(g + transition[1] / 10, 1)
        b = round(b + transition[2] / 10, 1)
        COLORS.append((r, g, b))

def color(n):
    z = complex(0, 0)
    c = n
    for n in range(len(COLORS)):
        z = z ** 2 + c
        if abs(z) > 2:
            return COLORS[n]
    return (0, 0, 0)


def get_data(c1, c2):
    d = []
    for i in np.linspace(c1.imag, c2.imag, num = 500):
        rvals = [complex(r, i) for r in np.linspace(c1.real, c2.real, num = 500)]
        d.append(list(map(color, rvals)))
    return d


# Interface
corner1 = (-2, -2)
corner2 = (2, 2)


def display_data(c1, c2):
    data = get_data(c1, c2)
    axes.imshow(list(reversed(data)), extent = [corner1[0], corner2[0], corner1[1], corner2[1]])
    plt.show()


def startzoom(event):
    global corner1, corner2
    if event.button:
        x = event.xdata
        y = event.ydata
        corner1 = corner2 = (x, y)


def stopzoom(event):
    global corner1, corner2
    if event.button:
        x = event.xdata
        y = event.ydata
        corner2 = (x, y)
        if corner1 == corner2:
            corner1, corner2 = (-2, -2), (2, 2)
        display_data(complex(*corner1), complex(*corner2))


# Put it all together
data = get_data(complex(*corner1), complex(*corner2))
figure, axes = plt.subplots()
axes.set_title("Mandelbrot Set")
axes.set_xlabel("Real")
axes.set_ylabel("Imaginary")
image = axes.imshow(list(reversed(data)), extent = [-2, 2, -2, 2])
figure.canvas.mpl_connect("button_press_event", startzoom)
figure.canvas.mpl_connect("button_release_event", stopzoom)
plt.show()

enter image description hereenter image description hereenter image description here

相关问题 更多 >