2

I am generating 2D morphogenic plots using tkinter. I find it incredibly slow. For example, this script takes almost 10 seconds on my 8-core Xeon:

#!/usr/bin/env python3

import random
import tkinter as tk

A = 3.419384662527591
B = 2.0158889752347022
C = 19.479697084985673
D = 61.006212908774614
F = 1.3449991745874286
G = 1.9590223710983992
H = 5.129501734860241
WIDTH = 800
HEIGHT = 600


class Morphogenic(tk.Frame):

    def __init__(self, root):
        tk.Frame.__init__(self, root)
        self.canvas = tk.Canvas(width=WIDTH, height=HEIGHT, borderwidth=1)
        self.canvas.pack(side="top", fill="both", expand=True)

    def rand(self):
        A = 3 + random.random() * 10
        B = 1 + random.random() * 5
        C = 1 + random.random() * 20
        D = 1 + random.random() * 200
        F = 1 + random.random() * 2
        G = 1 + random.random() * 20
        H = 1 + random.random() * 20

    def draw(self):
        points = [0] * HEIGHT
        points_space = [0] * HEIGHT
        points_energy = [0] * HEIGHT
        w = WIDTH
        h = HEIGHT
        min_x = 0

        last_x = 0
        last_y = 0

        while min_x < w:
            min_x = w
            lrand = 0

            for y in range(1, h):
                points_space[y] = points_space[y] + \
                    (points_space[y - 1] - points_space[y]) / F

            for y in range(0, h):
                lrand = lrand + (random.random() - 0.5) / C
                new_point = points[y] + points_space[y] + lrand
                points_space[y] = (new_point - points[y]) + \
                    points_energy[y] / G
                points_space[y] = points_space[y] + (A - points_space[y]) / D
                points_energy[y] = points_energy[y] / H

                if (points_space[y] < B):
                    points_energy[y] = points_space[y] - B
                    points_space[y] = B

                points[y] = points[y] + points_space[y]

                if (min_x > points[y]):
                    min_x = points[y]

                self.canvas.create_line(last_x, last_y, points[y], y)
                last_x = points[y]
                last_y = y


if __name__ == "__main__":
    root = tk.Tk()
    m = Morphogenic(root)
    m.pack(fill="both", expand=True)
    m.rand()
    m.draw()
    root.mainloop()

Is tkinter just too weak for this kind of work? Should I be looking at a different 2D library?

Mark Richman
  • 28,948
  • 25
  • 99
  • 159

2 Answers2

2

Your code is creating over 150,000 lines. This is starting to push the performance of the canvas widget. It can pretty easily handle thousands of items, even tens of thousands of items. 150,000 items is a bit more than it was designed to handle.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
1

I used Tk for an application as well.

It was an application with an auto generated GUI from XML files, and TK was simply too slow.

I Switched to PYside and have been very happy about it. Its not as easy to use as Tkinter, but its much faster and has a lot of posibilities

Svend Feldt
  • 758
  • 4
  • 17