Estou tentando fazer uma exibição do conjunto de Mandelbrot, com o seguinte código:
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['toolbar'] = 'None'
def mandelbrot(c, max_iter):
z = 0
for n in range(max_iter):
if abs(z) > 2:
return n
z = z*z + c
return max_iter
def mandelbrot_set(xmin, xmax, ymin, ymax, width, height, max_iter):
r1 = np.linspace(xmin, xmax, width)
r2 = np.linspace(ymin, ymax, height)
n3 = np.empty((width, height))
for i in range(width):
for j in range(height):
n3[i, j] = mandelbrot(r1[i] + 1j*r2[j], max_iter)
return n3.T
# Settings
xmin, xmax, ymin, ymax = -2.0, 1.0, -1.5, 1.5
width, height = 800, 800
max_iter = 256
# Generate Mandelbrot set
mandelbrot_image = mandelbrot_set(xmin, xmax, ymin, ymax, width, height, max_iter)
# Window
fig = plt.figure(figsize=(5, 5))
fig.canvas.manager.set_window_title('Mandelbrot Set')
ax = fig.add_axes([0, 0, 1, 1]) # Fill the whole window
ax.set_axis_off()
# Show fractal
ax.imshow(mandelbrot_image, extent=(xmin, xmax, ymin, ymax), cmap='hot')
plt.show()
Como posso ampliar o fractal continuamente, sem consumir muitos recursos? Estou usando um laptop de médio porte e, atualmente, a geração do fractal demora muito. Existe uma maneira mais rápida de fazer isso ao implementar um recurso de zoom?
Você está usando código Python para lidar com números NumPy individuais . Essa é a pior maneira. Já seria duas vezes mais rápido se você usasse números Python, usando
.tolist()
:Mas é melhor usar o NumPy corretamente, por exemplo, trabalhar em todos os pixels em paralelo, monitorando os valores (e seus índices) que ainda têm abs ≤ 2:
Agora, isso leva cerca de 0,17 segundos, em vez dos 6,7 segundos do seu original.
EDITAR:
Implementação do algoritmo de tempo de escape para o conjunto de Mandelbrot. Observe que existem muitas implementações e variações dele; por exemplo, a proposta anteriormente na galeria do Matplotlib é ligeiramente diferente da proposta no OP. Esta resposta é uma adaptação do exemplo do Matplotlib.
na minha máquina o seguinte tempo de execução é mantido (testado apenas com parâmetros como no OP):
rápido <- Kelly Bundy <- 4x - cartas <- 5x - Prometheus (OP) <- lento
ORIGINAL: melhorando o desempenho gráfico (veja também os comentários)
Algumas
matplotlib
melhorias de desempenho podem ser feitas ajustando algumas das configurações do matplotlibrc :Estilo rápido:
mplstyle.use('fast')
" define automaticamente os parâmetros de simplificação e fragmentação para configurações razoáveis para acelerar a plotagem de grandes quantidades de dados" . Em caso de combinação com outros estilos, aplique-o por último para evitar sobrescrever suas configurações.simplificação de segmentos de linha:
plt.rcParams['path.simplify_threshold'] = 1.0
: "controla o quanto os segmentos de linha são simplificados"A implementação de um recurso "semelhante ao zoom" pode ser feita com a técnica de blitting de uma animação .