0

I'm new to coding and in the moment I'm trying to code an application which tracks a movement from a simulation and visualize the movement in the plot window.

No break command seems to work.

Here is the updated code with the suggestion of @bf-g's answer below incoorporated:

def handle_close(evt):
    raise SystemExit('Closed figure, exit program.')

fig = plt.figure()
fig.canvas.mpl_connect('close_event', handle_close)# Definition der figure

while True:

    plt.clf() # vorherige Plots clearen

    for i in range(0, int(alpha_max), 5):
            plt.plot(Drehachse_x + Radius*np.cos((i+alpha_0)*np.pi/180), Drehachse_y + Radius*np.sin((i+alpha_0)*np.pi/180), color='red', marker='*', markersize=1)

    for i in range(0, int(alpha_max), 2):
            plt.plot(Drehachse_x + Radius_Heckklappe*np.cos((i+alpha_0+beta_0+delta)*np.pi/180), Drehachse_y + Radius_Heckklappe*np.sin((i+alpha_0+beta_0+delta)*np.pi/180), color='red', marker='*', markersize=1.5)


    alpha = "PATH"
    Schwerpunkt_x = "PATH"
    Schwerpunkt_y = "PATH"
    Spindel_Heck_x = "PATH"
    Spindel_Heck_y = "PATH"

    x=(Drehachse_x, Schwerpunkt_x)
    y=(Drehachse_y, Schwerpunkt_y)

    x1=(Spindel_Heck_x, Spindel_Karo_x)
    y1=(Spindel_Heck_y, Spindel_Karo_y)

    plt.axis('equal')
    plt.axis([3100, 3800, 600, 1400])

    plt.plot(x,y, color="blue", linewidth=2.0, linestyle="-", marker='o', label='$Heckklappe$')
    plt.plot(x1, y1, color="green", linewidth=2.0, linestyle="-", marker='o', label='$Spindel$')
    plt.plot(x_g_max, y_g_max, color="orange", linewidth=2.0, linestyle="--", marker='*', label='$Maximal$')
    plt.plot(x_g_min, y_g_min, color="red", linewidth=2.0, linestyle="--", marker='*', label='$Minimal$')

    plt.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),
               fancybox=True, shadow=True, ncol=5)

    plt.pause(0.001)
    plt.text(0.35, 0.5, 'Close Me!', dict(size=30))
    plt.draw()

It does what I want it to do, but if I try to close the plot window it just keeps opening up until I close the program.

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
Gan Zo
  • 25
  • 4

3 Answers3

1

I think it is because your plt.draw() is inside of the while loop, and it basically opens a new window every time it iterates in the while loop, and to fix it, you can put the plt.draw() outside the loop, and then break the loop when you want to draw the graph.

Bytes2048
  • 344
  • 1
  • 6
  • 16
  • Thanks for your quick answer!. I want the plot window to keep updating the plot until I close it. Which break command will allow me that ? – Gan Zo Jun 26 '19 at 05:34
  • @GanZo You can try `plt.clear()` before the `plt.plot(...)`: source from [this question](https://stackoverflow.com/questions/4098131/how-to-update-a-plot-in-matplotlib) – Bytes2048 Jun 26 '19 at 08:06
  • unfortunately that wasn't it – Gan Zo Jun 26 '19 at 08:25
0

You are looking for an event handler. The event you need to monitor is the closing of the figure. Define the figure outside of the infinite loop and add the event handler:

import matplotlib.pyplot as plt

def handle_close(evt):
    raise SystemExit('Closed figure, exit program.')

fig = plt.figure()
fig.canvas.mpl_connect('close_event', handle_close)

while True:
    plt.text(0.35, 0.5, 'Close Me!', dict(size=30))
    plt.show()
b-fg
  • 3,959
  • 2
  • 28
  • 44
  • Does it change something if I use "plt.schow()" instead of "plt.draw()" ? – Gan Zo Jun 26 '19 at 06:24
  • Yeah, this is just and example. Use the plt.draw() to update your plot. – b-fg Jun 26 '19 at 06:25
  • Please accept/upvote the answer if it resolved your question. – b-fg Jun 26 '19 at 07:16
  • Sorry I am new to coding. I don't really know why. But it didn't change how the program operates at all. Maybe there need to be a command like plt.close(fig) ? – Gan Zo Jun 26 '19 at 07:55
  • Yes, just indent `raise SystemExit('Closed figure, exit program.') ` correctly. – b-fg Jun 26 '19 at 08:27
  • like this ? if you mean that, then it was just a mistake here not in my code – Gan Zo Jun 26 '19 at 08:42
  • there was no error. the problem was just every time I tried to close the plot window it just kept opening up again... no error statement – Gan Zo Jul 02 '19 at 12:45
0

while True: will continue to do everything that's inside until the end of all days. So it's not well suited for a program flow that is to change at any point. Instead, you would want to introduce a condition that needs to be met for the loop to continue, while condition==True:.

In terms of code, the following just runs forever

import numpy as np
import matplotlib.pyplot as plt

plt.ion()

fig, ax = plt.subplots()

phi = 0
x = np.linspace(0,2*np.pi)
y = np.sin(x)
line, = ax.plot(x,y)

while True:
    phi += 0.1
    y = np.sin(x+phi)
    line.set_ydata(y)

    plt.pause(0.1)
    print(f"Still running; phi={phi}")

plt.ioff()
plt.show()

So we need to introduce a condition at which to not continue the loop.

import numpy as np
import matplotlib.pyplot as plt

plt.ion()

fig, ax = plt.subplots()

phi = 0
x = np.linspace(0,2*np.pi)
y = np.sin(x)
line, = ax.plot(x,y)

condition = True 

def on_close(evt=None):
    global condition
    condition = False

fig.canvas.mpl_connect("close_event", on_close)

while condition:
    phi += 0.1
    y = np.sin(x+phi)
    line.set_ydata(y)

    plt.pause(0.1)
    print(f"Still running; phi={phi}")

plt.ioff()
plt.show()

This is rather complicated, so matplotlib has a built-in animation module to do the same inside the program's event loop.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

fig, ax = plt.subplots()

phi = 0
x = np.linspace(0,2*np.pi)
y = np.sin(x)
line, = ax.plot(x,y)

def animate(i):
    phi = i/10
    y = np.sin(x+phi)
    line.set_ydata(y)

    print(f"Still running; phi={phi}")

ani = FuncAnimation(fig, animate) 

plt.show()
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712