You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mandelbrot集迭代滑块失效求助:默认值以上调节无响应

Mandelbrot集迭代滑块异常问题修复

问题概述

课程项目需实现带自定义色图和max_iter滑块的Mandelbrot集展示,色图单选按钮功能正常,但迭代滑块存在以下异常:

  • AI提供的修正代码仅在迭代次数低于默认值30时有效,调至100时视觉无实际变化
  • 手动修改初始max_iter为100后,滑块设为30的效果与正常30次迭代的结果完全不同,仅滑块设为100时效果符合预期

原代码(注释为波兰语,可忽略)

# sparametryzować liczbę iteracji
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import RadioButtons, Slider

fig, ax = plt.subplots()
plt.subplots_adjust(left=0.3)

# Rozmiary i obszar
width, height = 1500, 1500
x_min, x_max = -2, 0.5
y_min, y_max = -1.25, 1.25
max_iter = 30

# Siatka
x = np.linspace(x_min, x_max, width)
y = np.linspace(y_min, y_max, height)
X, Y = np.meshgrid(x, y)
C = X + 1j * Y

# Mandelbrot z użyciem pętli
Z = np.zeros(C.shape, dtype=complex)
M = np.zeros(C.shape, dtype=int)

axiter = plt.axes([0.25,0.05,0.65,0.03], facecolor="#777777")
iter_slider = Slider(axiter, "Ilość iteracji", 1, 100, valinit = 30, track_color="#777777",)

for k in range(max_iter):
    mask = np.abs(Z) <= 2.0
    Z[mask] = Z[mask]**2 + C[mask]
    M[mask] = k + 1

# Wyświetlenie fraktalu
img = ax.imshow(M, extent=(x_min, x_max, y_min, y_max), cmap='twilight', origin='lower')
ax.axis('equal')
ax.axis('off')

# RadioButtons do zmiany cmap
ax.set_title('Fraktal Mandelbrota', pad=10)
rax = plt.axes([0.05, 0.4, 0.15, 0.15])
radio = RadioButtons(rax, ('twilight', 'Spectral', 'inferno', 'pink', 'viridis', 'berlin'))
rax.set_title('Wybór mapy kolorów', pad=10)

def update(label):
    sliter=iter_slider.val
    
    max_iter = sliter
    for k in range(max_iter):
        mask = np.abs(Z) <= 2.0
        Z[mask] = Z[mask]**2 + C[mask]
        M[mask] = k + 1
    ax.imshow(M, extent=(x_min, x_max, y_min, y_max), cmap='twilight', origin='lower')
    img.set_cmap(label)
    fig.canvas.draw_idle()

radio.on_clicked(update)

plt.show()

AI提供的修正代码(注释为波兰语,可忽略)

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import RadioButtons, Slider

fig, ax = plt.subplots()
plt.subplots_adjust(left=0.3)

# Rozmiary i obszar
width, height = 1500, 1500
x_min, x_max = -2, 0.5
y_min, y_max = -1.25, 1.25
max_iter = 30

# Siatka
x = np.linspace(x_min, x_max, width)
y = np.linspace(y_min, y_max, height)
X, Y = np.meshgrid(x, y)
C = X + 1j * Y

# Mandelbrot z użyciem pętli
Z = np.zeros(C.shape, dtype=complex)
M = np.zeros(C.shape, dtype=int)

axiter = plt.axes([0.25,0.05,0.65,0.03], facecolor="#777777")
iter_slider = Slider(axiter, "Ilość iteracji", 1, 100, valinit=30, track_color="#777777")

for k in range(max_iter):
    mask = np.abs(Z) <= 2.0
    Z[mask] = Z[mask]**2 + C[mask]
    M[mask] = k + 1

# Wyświetlenie fraktalu
img = ax.imshow(M, extent=(x_min, x_max, y_min, y_max), cmap='twilight', origin='lower')
ax.axis('equal')
ax.axis('off')

# RadioButtons do zmiany cmap
ax.set_title('Fraktal Mandelbrota', pad=10)
rax = plt.axes([0.05, 0.4, 0.15, 0.15])
radio = RadioButtons(rax, ('twilight', 'Spectral', 'inferno', 'pink', 'viridis', 'berlin'))
rax.set_title('Wybór mapy kolorów', pad=10)

def redraw():
    max_iter = int(iter_slider.val)

    Z = np.zeros(C.shape, dtype=complex)
    M = np.zeros(C.shape, dtype=int)

    for k in range(max_iter):
        mask = np.abs(Z) <= 2.0
        Z[mask] = Z[mask]**2 + C[mask]
        M[mask] = k + 1

    img.set_data(M)
    img.set_cmap(radio.value_selected)
    fig.canvas.draw_idle()

def update(label):
    redraw()

def update_iter(val):
    redraw()

radio.on_clicked(update)
iter_slider.on_changed(update_iter)

plt.show()

效果对比

  • 手动设置100迭代效果:手动设置100次迭代效果
  • 滑块设置100迭代效果:滑块设置100次迭代效果
  • 初始max_iter设为100时,滑块设置30迭代效果:初始100迭代后滑块设为30的效果

问题根源

异常的核心原因是颜色映射的范围未随迭代次数动态更新:

  • matplotlib的imshow默认会根据初始数据的极值自动设置颜色范围(vmin和vmax)
  • 当迭代次数变化时,修正代码仅更新了数据M,但未调整颜色范围:
    • 初始max_iter=30时,vmax被设为30,滑块调至100后,M的最大值为100,但所有大于30的值会被映射到同一种颜色,视觉上无变化
    • 初始max_iter=100时,vmax被设为100,滑块调至30后,M的最大值为30,颜色范围仍为0-100,导致颜色对比度极低,显示异常

修复方案

在每次重绘时,手动更新颜色范围以匹配当前迭代次数的结果,只需修改redraw函数,添加img.set_clim(vmin=0, vmax=max_iter)即可:

修改后的完整代码

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import RadioButtons, Slider

fig, ax = plt.subplots()
plt.subplots_adjust(left=0.3)

# Rozmiary i obszar
width, height = 1500, 1500
x_min, x_max = -2, 0.5
y_min, y_max = -1.25, 1.25
max_iter = 30

# Siatka
x = np.linspace(x_min, x_max, width)
y = np.linspace(y_min, y_max, height)
X, Y = np.meshgrid(x, y)
C = X + 1j * Y

# Mandelbrot z użyciem pętli
Z = np.zeros(C.shape, dtype=complex)
M = np.zeros(C.shape, dtype=int)

axiter = plt.axes([0.25,0.05,0.65,0.03], facecolor="#777777")
iter_slider = Slider(axiter, "Ilość iteracji", 1, 100, valinit=30, track_color="#777777")

for k in range(max_iter):
    mask = np.abs(Z) <= 2.0
    Z[mask] = Z[mask]**2 + C[mask]
    M[mask] = k + 1

# Wyświetlenie fraktalu
img = ax.imshow(M, extent=(x_min, x_max, y_min, y_max), cmap='twilight', origin='lower')
ax.axis('equal')
ax.axis('off')

# RadioButtons do zmiany cmap
ax.set_title('Fraktal Mandelbrota', pad=10)
rax = plt.axes([0.05, 0.4, 0.15, 0.15])
radio = RadioButtons(rax, ('twilight', 'Spectral', 'inferno', 'pink', 'viridis', 'berlin'))
rax.set_title('Wybór mapy kolorów', pad=10)

def redraw():
    max_iter = int(iter_slider.val)

    Z = np.zeros(C.shape, dtype=complex)
    M = np.zeros(C.shape, dtype=int)

    for k in range(max_iter):
        mask = np.abs(Z) <= 2.0
        Z[mask] = Z[mask]**2 + C[mask]
        M[mask] = k + 1

    img.set_data(M)
    img.set_cmap(radio.value_selected)
    # 动态更新颜色范围,匹配当前迭代次数
    img.set_clim(vmin=0, vmax=max_iter)
    fig.canvas.draw_idle()

def update(label):
    redraw()

def update_iter(val):
    redraw()

radio.on_clicked(update)
iter_slider.on_changed(update_iter)

plt.show()

内容的提问来源于stack exchange,提问作者Helewapo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 14:22:28