MarcSkovMadsen commited on
Commit
4f7cf9b
·
verified ·
1 Parent(s): 2ff4bf3

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +139 -0
app.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ ## Explanation
3
+
4
+ The *Mandelbrot set* is a fascinating two-dimensional fractal that is defined by a simple mathematical formula but exhibits remarkable complexity, especially when magnified. It is widely known for its intricate patterns and aesthetic appeal.
5
+
6
+ The set is defined on the complex plane as the set of complex numbers $$ c $$ for which the iterative function $$ f_c(z) = z^2 + c $$ does not diverge to infinity when starting at $$ z = 0 $$. In other words, the sequence $$ f_c(0) $$, $$ f_c(f_c(0)) $$, and so on, remains bounded in absolute value.
7
+
8
+ In this implementation, the sequence is computed iteratively. The process stops if the magnitude of the number exceeds 4, indicating that it has diverged. The color in the resulting image reflects the number of iterations needed to determine if the point belongs to the Mandelbrot set.
9
+ """
10
+
11
+ import colorcet as cc
12
+ import holoviews as hv
13
+ import numpy as np
14
+ import panel as pn
15
+ from holoviews.streams import RangeXY
16
+ from numba import jit
17
+
18
+ pn.extension("mathjax")
19
+
20
+ DEFAULT_COLOR_MAP = [
21
+ "#0b2f4c", # Deep blue
22
+ "#164e80", # Medium blue
23
+ "#208ed6", # Bright blue
24
+ "#30a0e0", # Aqua blue
25
+ "#71c4f2", # Light sky blue
26
+ "#b4e4fa", # Pale blue
27
+ "#f5f1b8", # Soft yellow
28
+ "#f0c366", # Light orange
29
+ "#f28d35", # Bright orange
30
+ "#e0471e", # Fiery red
31
+ "#a83e1c", # Deep red-brown
32
+ "#662b12", # Dark brown
33
+ "#2d1107", # Almost black
34
+ "black", # Pure black
35
+ ]
36
+ ACCENT = DEFAULT_COLOR_MAP[1]
37
+
38
+
39
+ @jit
40
+ def mandel(x, y, max_iters):
41
+ """
42
+ Given the real and imaginary parts of a complex number,
43
+ determine if it is a candidate for membership in the Mandelbrot
44
+ set given a fixed number of iterations.
45
+ """
46
+ i = 0
47
+ c = complex(x, y)
48
+ z = 0.0j
49
+ for i in range(max_iters):
50
+ z = z * z + c
51
+ if (z.real * z.real + z.imag * z.imag) >= 4:
52
+ return i
53
+
54
+ return 255
55
+
56
+
57
+ @jit
58
+ def create_fractal(min_x, max_x, min_y, max_y, image, iters):
59
+ height = image.shape[0]
60
+ width = image.shape[1]
61
+
62
+ pixel_size_x = (max_x - min_x) / width
63
+ pixel_size_y = (max_y - min_y) / height
64
+ for x in range(width):
65
+ real = min_x + x * pixel_size_x
66
+ for y in range(height):
67
+ imag = min_y + y * pixel_size_y
68
+ color = mandel(real, imag, iters)
69
+ image[y, x] = color
70
+
71
+ return image
72
+
73
+
74
+ def get_fractal(x_range, y_range, iters=200, cmap="set1", width=1200, height=1200):
75
+ (x0, x1), (y0, y1) = x_range, y_range
76
+ image = np.zeros((width, height), dtype=np.uint8)
77
+ return hv.Image(
78
+ create_fractal(x0, x1, -y1, -y0, image, iters), bounds=(x0, y0, x1, y1), rtol=1e-9
79
+ ).opts(
80
+ colorbar=True,
81
+ cmap=cmap,
82
+ xlabel="Real",
83
+ ylabel="Imaginary",
84
+ title="Complex Plane",
85
+ clabel="Number of Iterations",
86
+ clim=(0, 255),
87
+ tools=["hover"],
88
+ )
89
+
90
+
91
+ range_stream = RangeXY(x_range=(-1.0, 1.0), y_range=(-1.0, 1.0))
92
+
93
+ max_iterations = pn.widgets.IntSlider(value=200, start=1, end=254, name="Max Iterations")
94
+
95
+ height = pn.widgets.IntSlider(
96
+ value=800,
97
+ start=100,
98
+ end=2000,
99
+ name="Image height (pixels)",
100
+ )
101
+ width = pn.widgets.IntSlider(
102
+ value=1000,
103
+ start=100,
104
+ end=2000,
105
+ name="Image width (pixels)",
106
+ )
107
+
108
+
109
+ palette = {"default": DEFAULT_COLOR_MAP}
110
+ palette.update(cc.palette)
111
+ cmap = pn.widgets.ColorMap(
112
+ value=DEFAULT_COLOR_MAP,
113
+ options=palette,
114
+ ncols=3,
115
+ swatch_width=100,
116
+ sizing_mode="stretch_width",
117
+ name="Color Map",
118
+ )
119
+ dmap = hv.DynamicMap(
120
+ pn.bind(
121
+ get_fractal,
122
+ iters=max_iterations,
123
+ x_range=range_stream.param.x_range,
124
+ y_range=range_stream.param.y_range,
125
+ cmap=cmap,
126
+ height=height,
127
+ width=width,
128
+ )
129
+ )
130
+ dmap_panel = pn.panel(dmap, height=height, width=width)
131
+ pn.template.FastListTemplate(
132
+ site="Awesome Panel",
133
+ site_url="./",
134
+ title="Mandelbrot",
135
+ sidebar=["## Settings", cmap, max_iterations, height, width, pn.pane.Markdown(__doc__)],
136
+ main=[dmap_panel],
137
+ accent=ACCENT,
138
+ main_layout=None,
139
+ ).servable()