4

I am trying to draw the mandelbrot sequence with python's turtle graphics. I am using two classes, one to represent the mandelbrot sequence.

class Mandelbrot:
def __init__(self,c,limit=50):
    self.__limit = int(limit)
    self.__colormap = ['black','white']
    self.__cardinality = limit
    z = 0
    for i in range(limit):
        z = z * z + c


        if abs(z) > 2:
            self.__cardinality = i
            return



def getColor(self):
    if self.__cardinality == self.__limit:
        return self.__colormap[0]
    return self.__colormap[1]

The other class represents the turtle display.

import turtle
from mandelbrot import *

class Display:
    def __init__(self):
        self.t = turtle.Turtle()
        self.t.ht();self.t.turtlesize(1)
        self.t.speed(0)
        turtle.tracer(2000,0)


    for x in range(-150,151):
        for y in range(-150,151):
            self.t.color(Mandelbrot(turtleConvert(x,y)).getColor())
            self.t.goto(x,y)



def turtleConvert(x,y): #converts from turtle pixels to the complex plane
    return complex((x/300)*4,(y/300)*4)

When I make an instance of the display class, the program runs but only prints the lower half of the fractal. Could anyone provide a solution?

This is a picture of my result.

Fractal

furas
  • 134,197
  • 12
  • 106
  • 148
Connor Simone
  • 41
  • 1
  • 2

2 Answers2

2

On my system (OSX), your program produces the entire fractal:

enter image description here

So this may be Python turtle or Tkinter implementation specific. (Add your system details to your question or as a comment after it.)

I will address a couple of unrelated issues, however. First, you create a new Mandelbrot instance for every point you plot -- you only need one instance that you invoke as needed:

class Mandelbrot:
    def __init__(self, limit=50):
        self.__limit = int(limit)
        self.__colormap = ['black', 'white']
        self.__cardinality = self.__limit

    def computeCardinality(self, c):
        z = 0
        self.__cardinality = self.__limit

        for i in range(self.__limit):
            z = z * z + c

            if abs(z) > 2:
                self.__cardinality = i
                return

    def getColor(self):
        if self.__cardinality == self.__limit:
            return self.__colormap[0]
        return self.__colormap[1]

Your main program revised to use this mandelbrot.py, and changing your tracer() logic slightly:

from turtle import Turtle, Screen
from mandelbrot import *

class Display:
    def __init__(self, screen):
        self.t = Turtle(visible=False)
        self.t.speed('fastest')
        screen.tracer(0)

        mandelbrot = Mandelbrot()

        for x in range(-150, 151):
            for y in range(-150, 151):
                mandelbrot.computeCardinality(turtleConvert(x, y))
                self.t.color(mandelbrot.getColor())
                self.t.goto(x, y)
            screen.update()

        screen.tracer(1)

def turtleConvert(x, y):  # converts from turtle pixels to the complex plane
    return complex(x / 75, y / 75)

screen = Screen()
dummy = Display(screen)
screen.mainloop()

The second issue is that if you look at the image I generated above, you'll see slight curved lines across it. You may or may not experience these, again depending on the system you're using. If you do get these, or simply want to learn about them, see:

cdlane
  • 40,441
  • 5
  • 32
  • 81
2

I have the same problem on Linux Mint but I see it draws upper part and later it removes it.

Problem is because goto(x,y) draws white line when turtle moves from top to bottom in next column - ie. from (0, 150) to (1, -150) - and this line removes part of your image.

You have to move it manually without drawing line

    for x in range(-150,151):
        for y in range(-150,151):
            self.t.color(Mandelbrot(turtleConvert(x,y)).getColor())
            self.t.goto(x,y)

        # move to bottom in next column without creating white line
        self.t.up()
        self.t.goto(x+1, -150)
        self.t.down()

Or move it before you start every new column

    for x in range(-150, 151):
        # move to bottom without creating white line
        self.t.up()
        self.t.goto(x, -150)
        self.t.down()

        for y in range(-150, 151):
            self.t.color(Mandelbrot(turtleConvert(x,y)).getColor())
            self.t.goto(x,y)
furas
  • 134,197
  • 12
  • 106
  • 148
  • 1
    Nice catch! (+1) I've seen this error with similar graphics, [Turtle graphics drawing over itself](https://stackoverflow.com/a/40985057/5771269), but missed it this time since my system displayed a complete image. – cdlane Dec 06 '17 at 19:56