-1

How can I avoid this while True Loop. I have to run def func(i) infinite times. The reason for avoiding this while True loop is that whenever I create two classes, one class having this piece of code and another class having a button to access this piece of code when button is pressed, but the problem I get is that I cannot integrate this matplotlib within the tkinter window. The button is shown separately and the matplotlib is running separately. But when I remove while loop then it somehow solves the problem but then there is no infinite loop.

import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt
import numpy as np
import tkinter as tk
from tkinter import *
import matplotlib.animation as animation

j=0
fig = plt.figure()
ax1 = fig.add_axes([0.85, 0.093, 0.04, 0.8])
cax = fig.add_subplot(1, 1, 1)

H = np.array([[1, 2, 3, 1], [4, 5, 6, 10], [3, 7, 8, 4], [10, 5, 3, 1]])
Z = np.array([[3, 290, 600], [1011, 230, 830], [152, 750, 5]])

while True:
    def func(i):
        global j
        if j == 0:
            j += 1
            rows, cols = H.shape

            im = plt.imshow(H, interpolation='nearest',
                            extent=[0, cols, 0, rows],
                            cmap='bwr', vmin=0, vmax=10)
            fig.colorbar(im, cax=ax1, orientation='vertical')


        elif j == 1:

            j -= 1
            rows, cols = H.shape

            im = plt.imshow(Z, interpolation='nearest', cmap='Spectral', vmin=0, vmax=1023,extent=[0, cols, 0, rows])
            v = np.linspace(0, 1023, 15, endpoint=True)
            fig.colorbar(im, cax=ax1, orientation='vertical', ticks=v)


    ani = animation.FuncAnimation(fig, func, interval=1000)
    plt.show()
    plt.close()
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
  • 7
    I don't get why you want to define a function over and over, looks like a big designing bug to me. Can you explain a bit more extensively what are you trying to accomplish? – alec_djinn Jun 02 '17 at 12:19
  • Additionally there is no button in the code. However it seems the button is the reason to use this structure of an animation loop inside a while loop. But since we don't know the problem of the button, it's impossible to help here. From what you're saying, "I cannot integrate this matplotlib within the tkinter window" seems to be the **real problem** and this it may make sense to ask about this problem instead of some other one. – ImportanceOfBeingErnest Jun 02 '17 at 12:30
  • @alec_djinn I have been given the task by my teacher to build arrays and display them using matplotlib again and again. And then I have to integrate matplotlib in tkinter. – Hammad Ullah Jun 02 '17 at 13:31
  • I've proposed an edit to clarify the infinite loop question. The code style of repeatedly calling `def` isn't relevant to the question - perhaps it could be removed to simplify the question? – Joe P Jun 02 '17 at 14:51
  • I think it's clear to everyone that the function definition can happen outside the loop but that this is simply a question of efficiency and not the source of the problem. The real problem still stays a mystery as OP refuses to refine and clarify the problem description. He wants to remove the infinite loop but states that he cannot do it because then "then there is no infinite loop" anymore. What is clearly lacking here is **the reason** to have this infinite loop at the first place. And for that one would need to know the role of "the button" and the true meaning of "cannot". – ImportanceOfBeingErnest Jun 02 '17 at 17:07

1 Answers1

1

Code style: can you avoid running the def repeatedly by instead defining two functions, func0(i) for the j==0 case and func1(i) for the j==1 case? (I assume func has to have a predefined signature and you can't add j as a parameter to it.) And then change the body of the infinite loop to

ani = animation.FuncAnimation(fig, func0, interval=1000)
plt.show()
plt.close()
ani = animation.FuncAnimation(fig, func1, interval=1000)
plt.show()
plt.close()

Use a timer or a thread instead: it's a bad idea to have infinite loops in a GUI app, at least in the thread that's processing events. Can you put the infinite loop into a separate thread (caution, threads are not for the faint-hearted) or change it into a repeating timer-driven event (with no loop in the event)?

More on timers: The idea is to use a timer to run one loop, then return to the GUI so it gets updated and is responsive. Tkinter supports timers using the after() method of the root window. I don't know if it supports repeating timers but all you have to do is restart the timer at the end of your timer event.

There are some examples in How to create a timer using tkinter?, How to create a timer using tkinter? and Python - Countdown timer within a tkinter canvas.

(Sorry, I would have preferred to add this as a comment but I don't have enough reputation here.)

Joe P
  • 466
  • 3
  • 8
  • Thanks for the answer. How can I call a function again and again if I don't use loops? Remember that I have to integrate matplotlib into tkinter window for the purpose of GUI design. – Hammad Ullah Jun 02 '17 at 13:34
  • Edited my answer with a bit more explanation and links to some examples, hope that helps – Joe P Jun 02 '17 at 13:46
  • @JoeP maybe you start by answering questions that **can** be answered instead of trying to answer questions which are too unclear. This would allow you to get the required reputation to comment pretty easily (just two upvotes I guess). Unclear questions like this should rather be left unanswered such that the questioner is forced to edit it and be more clear instead of starting an inifinte discussion below an answer, which is not really an answer. – ImportanceOfBeingErnest Jun 02 '17 at 14:05
  • @JoeP I really appreciate that. – Hammad Ullah Jun 02 '17 at 14:06
  • @ImportanceOfBeingErnest the question is How to avoid while true: loop ? Do you want a more more straight forward question than this ?? Just getting high reputation isn't the whole thing. – Hammad Ullah Jun 02 '17 at 14:09
  • @Hammad The question is not what *I* want, but what *you* want. Do you want a solution to the problem? If so, write a question with a clear problem description. – ImportanceOfBeingErnest Jun 02 '17 at 14:14
  • @ImportanceOfBeingErnest In this specific case, the question was **not** too unclear to attempt an answer; using a timer instead of an infinite loop is the answer; and in cases like this, people may not understand enough to write a clear question without help. Anyway, I have sorted out my reputation via another strategy. – Joe P Jun 02 '17 at 14:47
  • Maybe you want to read about the [XYproblem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) – ImportanceOfBeingErnest Jun 02 '17 at 14:55