2

これがmatplotlib/pythonのバグかどうかはわかりませんが、emacsから次のコマンドを実行すると、Figureウィンドウの[x]をクリックしてmatplotlibプロセスを強制終了できなくなります。効果はありません。emacsが起動した特定のプロセスを終了するためのコマンド(グーグル、運がない)はありますか?バッファを見つけて実行することでプロセスをC-x k強制終了できますが、実行中のすべてのPythonプロセスを強制終了する方法はありますか?

#Simple circular box simulator, part of part_sim
#Restructure to import into gravity() or coloumb () or wind() or pressure()
#Or to use all forces: sim_full()
#Note: Implement crashing as backbone to all forces
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial.distance import pdist, squareform

N = 100                                             #Number of particles
R = 10000                                           #Box width
pR= 5                                               #Particle radius

r = np.random.randint(0, R, (N,2))                  #Position vector
v = np.random.randint(-R/100,R/100,(N,2))           #velocity vector
a = np.array([0,-10])                               #Forces
v_limit = R/2                                       #Speedlimit


plt.ion()
line, = plt.plot([],'o')
line2, = plt.plot([],'o')                           #Track a particle
plt.axis([0,R+pR,0,R+pR]


while True:

    v=v+a                                           #Advance
    r=r+v

    #Collision tests
    r_hit_x0 = np.where(r[:,0]<0)                   #Hit floor?
    r_hit_x1 = np.where(r[:,0]>R)                   #Hit roof?
    r_hit_LR = np.where(r[:,1]<0)                   #Left wall?
    r_hit_RR = np.where(r[:,1]>R)                   #Right wall?


    #Stop at walls
    r[r_hit_x0,0] = 0
    r[r_hit_x1,0] = R
    r[r_hit_LR,1] = 0
    r[r_hit_RR,1] = R

    #Reverse velocities
    v[r_hit_x0,0] = -0.9*v[r_hit_x0,0]
    v[r_hit_x1,0] = -v[r_hit_x1,0]
    v[r_hit_LR,1] = -0.95*v[r_hit_LR,1]
    v[r_hit_RR,1] = -0.99*v[r_hit_RR,1]

    #Collisions
    D = squareform(pdist(r))
    ind1, ind2 = np.where(D < pR)
    unique = (ind1 < ind2)
    ind1 = ind1[unique]
    ind2 = ind2[unique]

    for i1, i2 in zip(ind1, ind2):
        eps = np.random.rand()
        vtot= v[i1,:]+v[i2,:]
        v[i1,:] = -(1-eps)*vtot
        v[i2,:] = -eps*vtot

    line.set_ydata(r[:,1])
    line.set_xdata(r[:,0])
    line2.set_ydata(r[:N/5,1])
    line2.set_xdata(r[:N/5,0])
    plt.draw()
4

1 に答える 1

2

C-c C-\SIGQUITでプログラムを強制終了しますが、それはプログラムを終了するための適切な方法ではありません。

または、バックエンドをに変更するとTkAggC-c C-cプログラムも終了しますが(これも不正に)、ウィンドウを閉じようとしても機能しません。

   import numpy as np
   import matplotlib as mpl
   mpl.use('TkAgg') # do this before importing pyplot
   import matplotlib.pyplot as plt

完全で堅牢なソリューションではplt.ion()、Tk、pygtk、wxpython、pyqtなどのGUIフレームワークを削除し、matplotlibFigureCanvasにGUIウィンドウを埋め込む必要があります。


Tkを使用した例を次に示します。

"""
http://stackoverflow.com/q/13660042/190597
Simple circular box simulator, part of part_sim
Restructure to import into gravity() or coloumb () or wind() or pressure()
Or to use all forces: sim_full()
Note: Implement crashing as backbone to all forces
"""

import tkinter as tk
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.figure as mplfig
import scipy.spatial.distance as dist
import matplotlib.backends.backend_tkagg as tkagg

class App(object):
    def __init__(self, master):
        self.master = master
        self.fig = mplfig.Figure(figsize = (5, 4), dpi = 100)
        self.ax = self.fig.add_subplot(111)
        self.canvas = canvas = tkagg.FigureCanvasTkAgg(self.fig, master)
        canvas.get_tk_widget().pack(side = tk.TOP, fill = tk.BOTH, expand = 1)
        self.toolbar = toolbar = tkagg.NavigationToolbar2TkAgg(canvas, master)
        self.button = button = tk.Button(master, text = 'Quit', command = master.quit)
        button.pack(side = tk.BOTTOM)
        toolbar.update()
        self.update = self.animate().__next__
        master.after(10, self.update) 
        canvas.show()

    def animate(self):
        N = 100                                             #Number of particles
        R = 10000                                           #Box width
        pR= 5                                               #Particle radius

        r = np.random.randint(0, R, (N,2))                  #Position vector
        v = np.random.randint(-R/100,R/100,(N,2))           #velocity vector
        a = np.array([0,-10])                               #Forces
        v_limit = R/2                                       #Speedlimit

        line, = self.ax.plot([],'o')
        line2, = self.ax.plot([],'o')                           #Track a particle
        self.ax.set_xlim(0, R+pR)
        self.ax.set_ylim(0, R+pR)        

        while True:
            v=v+a                                           #Advance
            r=r+v

            #Collision tests
            r_hit_x0 = np.where(r[:,0]<0)                   #Hit floor?
            r_hit_x1 = np.where(r[:,0]>R)                   #Hit roof?
            r_hit_LR = np.where(r[:,1]<0)                   #Left wall?
            r_hit_RR = np.where(r[:,1]>R)                   #Right wall?

            #Stop at walls
            r[r_hit_x0,0] = 0
            r[r_hit_x1,0] = R
            r[r_hit_LR,1] = 0
            r[r_hit_RR,1] = R

            #Reverse velocities
            v[r_hit_x0,0] = -0.9*v[r_hit_x0,0]
            v[r_hit_x1,0] = -v[r_hit_x1,0]
            v[r_hit_LR,1] = -0.95*v[r_hit_LR,1]
            v[r_hit_RR,1] = -0.99*v[r_hit_RR,1]

            #Collisions
            D = dist.squareform(dist.pdist(r))
            ind1, ind2 = np.where(D < pR)
            unique = (ind1 < ind2)
            ind1 = ind1[unique]
            ind2 = ind2[unique]

            for i1, i2 in zip(ind1, ind2):
                eps = np.random.rand()
                vtot= v[i1,:]+v[i2,:]
                v[i1,:] = -(1-eps)*vtot
                v[i2,:] = -eps*vtot

            line.set_ydata(r[:,1])
            line.set_xdata(r[:,0])
            line2.set_ydata(r[:N//5,1])
            line2.set_xdata(r[:N//5,0])
            self.canvas.draw()
            self.master.after(1, self.update) 
            yield

def main():
    root = tk.Tk()
    app = App(root)
    tk.mainloop()

if __name__ == '__main__':
    main()
于 2012-12-01T14:20:53.653 に答える