Created
January 22, 2011 16:38
-
-
Save tomhartley/791228 to your computer and use it in GitHub Desktop.
Generates and renders the Mandelbrot Set using the matplotlib library
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from pylab import * | |
from math import log | |
from Tkinter import Tk | |
from tkFileDialog import * | |
import csv | |
H = 500 | |
iterations = 30 | |
ColorList = [] | |
#Majority of processing work completed here. | |
#Calculates how close a point is to the mandelbrot set | |
def mandelbrot(real, imag): | |
#z = complex(-0.726895347709114071439, 0.188887129043845954792) | |
z = complex(0,0) | |
c = complex(real, imag) | |
dropOutLevel = 0 | |
for i in range(0, iterations): | |
if abs(z) < 2: | |
z = z**2 + c | |
dropOutLevel += 1 | |
else: | |
break | |
z = z**2 + c | |
z = z**2 + c | |
z = z**2 + c | |
z = z**2 + c | |
return dropOutLevel,z | |
#Interpolates (Smooths) between 2 different colours | |
def interpolateC(color,endColor,left): | |
if left == 0: | |
return color | |
rStart = color[0] | |
gStart = color[1] | |
bStart = color[2] | |
rEnd = endColor[0] | |
gEnd = endColor[1] | |
bEnd = endColor[2] | |
rDiff = rEnd-rStart | |
gDiff = gEnd-gStart | |
bDiff = bEnd-bStart | |
rInc = float(rDiff)/left | |
gInc = float(gDiff)/left | |
bInc = float(bDiff)/left | |
#print (str(left)) | |
return [rStart+rInc,gStart+gInc,bStart+bInc] | |
#Reads colour stops from a file chosen by the user using the tkinter library | |
def getPoints(): | |
Tk().withdraw() # we don't want a full GUI, so keep the root window from appearing | |
filename = askopenfilename() # show an "Open" dialog box and return the path to the selected file | |
reader = csv.reader(open(filename, "rb"), delimiter=',') | |
pointsList = [] | |
for row in reader: | |
colorList = [] | |
for a in row: | |
colorList.append(float(a)/255) | |
pointsList.append(colorList) | |
backwards = pointsList[0:-1] | |
backwards.reverse() | |
return pointsList+backwards | |
#Gets the location to save the file | |
def getSaveLocation(): | |
Tk().withdraw() | |
savefile = asksaveasfilename(defaultextension='.png') | |
return savefile | |
#Sets up a list of colours for the rendering to use from the points file | |
def colorList(): | |
cols = [] | |
points = getPoints() | |
eachLength = H/(len(points)-1) | |
howmanytogo = eachLength | |
for a in range(1,len(points)): | |
cols.append(points[a-1]) | |
for i in range (0,eachLength): | |
cols.append(interpolateC(cols[-1],points[a],howmanytogo)) | |
howmanytogo += -1 | |
howmanytogo = eachLength | |
global ColorList | |
ColorList = cols | |
#Turns a number from v() into a colour for the renderer to display | |
def toColor(a): | |
a=a*85 | |
a = int(a)%H | |
try: | |
return ColorList[int(a)] | |
except IndexError: | |
print a | |
print len(ColorList) | |
return ColorList[0] | |
#Smooths the numbers from mandelbrot() to create an even gradient | |
def v(z,n): | |
try: | |
x = n + 1 - log2(log2(abs(z)))/log2(2) | |
return x | |
except ValueError: | |
print(str(z)) | |
return 0 | |
#Initialise, get inputs | |
colorList() | |
saveFile = getSaveLocation() | |
wDensity = int(raw_input("What width?")) | |
hDensity = int(raw_input("What height?")) | |
x_ords = [] | |
y_ords = [] | |
colors = [] | |
left = float(raw_input("What is the leftmost value? ")) | |
right = float(raw_input("What is the rightmost value? ")) | |
bottom = float(raw_input("What is the bottommost value? ")) | |
top = float(raw_input("What is the topmost value? ")) | |
print "Calculating... " | |
w = right - left | |
h = top - bottom | |
wGap = w/wDensity | |
hGap = h/hDensity | |
wPercentageGap = w/100 | |
a = left | |
perc = 0 | |
print "0%" | |
#Calculate for each value and add to a list for rendering | |
while a < right: | |
b = bottom | |
while b < top: | |
x_ords.append(a) | |
y_ords.append(b) | |
n, z = mandelbrot(a,b) | |
if (n == iterations): | |
col = [0.0,0.0,0.0] | |
else: | |
col = toColor(v(z,n)) | |
#print col | |
colors.append(col) | |
b += hGap | |
a += wGap | |
#Print percentage | |
curPerc = ((right-a)/w) * 100 | |
if curPerc > perc+10: | |
perc += 10 | |
print str(perc),"%" | |
if curPerc > perc+5: | |
perc += 5 | |
print str(perc),"%" | |
#render and save the image | |
print "Rendering... " | |
autoscale(tight=True) | |
scatter(x_ords, y_ords, s=1, c=colors, linewidths=0) | |
F = gcf() | |
F.set_size_inches(wDensity/80,hDensity/80) | |
F.savefig(saveFile) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment