มีวิธีแยกตัวแปลง matplotlib เพื่อให้การคำนวณสามารถดำเนินต่อไปได้หรือไม่?


258

หลังจากคำแนะนำเหล่านี้ในล่าม Python จะได้หน้าต่างพร้อมพล็อต:

from matplotlib.pyplot import *
plot([1,2,3])
show()
# other code

น่าเสียดายที่ฉันไม่รู้วิธีดำเนินการสำรวจตัวเลขที่สร้างขึ้นแบบโต้ตอบต่อไปshow()ในขณะที่โปรแกรมทำการคำนวณเพิ่มเติม

เป็นไปได้หรือไม่? บางครั้งการคำนวณมีความยาวและมันจะช่วยถ้าพวกเขาจะดำเนินการในระหว่างการตรวจสอบผลกลาง


5
ฉันไม่สามารถยืนยันได้ว่าโซลูชันที่เลือกจาก nosklo เมื่อ 16:52 ใช้งานได้ สำหรับฉันวาดไม่ได้เปิดหน้าต่างเพื่อแสดงพล็อตเฉพาะการปิดกั้นแสดงที่ปลายแสดงวิธีการแก้ปัญหา อย่างไรก็ตามคำตอบของเขาตั้งแต่เวลา 17:00 น. ถูกต้อง การสลับโหมดโต้ตอบผ่านion()แก้ไขปัญหา
H. Brandsmeier

หากคุณเป็นโปรแกรมเมอร์ขั้นสูงคุณสามารถใช้งานได้os.fork()แต่โปรดจำไว้ว่าการใช้งานos.fork()นั้นอาจเป็นเรื่องยุ่งยากเพราะคุณกำลังสร้างกระบวนการใหม่โดยการคัดลอกกระบวนการเก่า
เทรเวอร์บอยด์สมิ ธ

คำตอบ:


214

ใช้ matplotlibโทรที่จะไม่บล็อก:

การใช้draw():

from matplotlib.pyplot import plot, draw, show
plot([1,2,3])
draw()
print 'continue computation'

# at the end call show to ensure window won't close.
show()

ใช้โหมดโต้ตอบ:

from matplotlib.pyplot import plot, ion, show
ion() # enables interactive mode
plot([1,2,3]) # result shows immediatelly (implicit draw())

print 'continue computation'

# at the end call show to ensure window won't close.
show()

28
ด้วย matplotlib 0.98.3 การนำเข้าที่ถูกต้องมาจากการวางแผนการนำเข้าของ matplotlib.pyplot วาดแสดง
meteore

112
draw()ใช้งานไม่ได้สำหรับฉันมันไม่เปิดหน้าต่างใด ๆ อย่างไรก็ตามการใช้show(block=False)แทนที่จะdraw()ดูเหมือนจะทำเคล็ดลับใน matplotlib 1.1
rumpel

4
@nosklo คุณเห็นไหม คุณทำให้เป็นบทช่วยสอนการ
Jan

4
@noskolo จะเกิดอะไรขึ้นถ้าฉันมีตัวเลขหลายตัว, จะทำพล็อตและแสดง Fig1 ในขณะที่ทำพื้นหลังต่อไปได้อย่างไร? ฉันต้องการให้ตัวเลขนี้ถูกเปิดจนกระทั่งรูปถัดไปที่ถูกสร้างขึ้นดังนั้นในที่สุดฉันก็เปิดมะเดื่อทั้งหมดและรหัสจะเสร็จสิ้น ด้วยโซลูชันปัจจุบันของคุณมันทำให้ฉันรอปิด Fig1 แล้วรหัสก็จะดำเนินต่อไป ขอบคุณ !!
ฟิสิกส์

9
draw()ไม่ได้ผลสำหรับฉันด้วยเช่นกันเท่านั้นpause(0.001): stackoverflow.com/questions/28269157/ …
NumesSanguis

133

ใช้คำหลัก 'บล็อก' เพื่อลบล้างพฤติกรรมการบล็อกเช่น

from matplotlib.pyplot import show, plot

plot(1)  
show(block=False)

# your code

เพื่อดำเนินการต่อรหัสของคุณ


17
แต่สิ่งนี้จะปิดหน้าต่างพล็อตทันทีจะไม่เปิดพล็อต
LWZ

8
ใช่มันเป็นเรื่องจริงถ้าคุณเรียกสคริปต์ของคุณจากบรรทัดคำสั่ง หากคุณอยู่ในเปลือก Ipython หน้าต่างจะไม่ถูกปิด
Jan

1
ตรวจสอบคำตอบของ @Nico สำหรับเคล็ดลับที่จะเปิดหน้าต่างทิ้งไว้ในกรณีทั่วไป
Jan

2
สำหรับฉันการดำเนินการนี้จะไม่ปิดหน้าต่างในทันทีเมื่อสคริปต์เสร็จสิ้น (เพื่อให้คุณสามารถบล็อกในตอนท้ายของสคริปต์ได้ด้วยตนเองหากคุณต้องการให้สคริปต์เปิดอยู่)
ยืม

ใช่หน้าต่างที่ไม่ได้ปิดกั้นจะปิดเมื่อออกจากสคริปต์ คุณสามารถ (a) อนุญาตการบล็อกพล็อตสุดท้ายของคุณหรือ (b) ไม่ออกจากสคริปต์ (อาจขอให้ป้อนข้อมูล: "กด <Enter> เพื่อออกจากพล็อต" หรืออะไรทำนองนั้น)
Daniel Goldfarb

29

มันจะดีกว่าที่จะตรวจสอบกับห้องสมุดที่คุณใช้อยู่เสมอหากมันรองรับการใช้งานในการไม่บล็อกทาง

แต่ถ้าคุณต้องการวิธีแก้ปัญหาแบบทั่วไปหรือถ้าไม่มีวิธีอื่นคุณสามารถเรียกใช้สิ่งที่บล็อกในกระบวนการแยกโดยใช้multprocessingโมดูลที่รวมอยู่ในหลาม การคำนวณจะดำเนินต่อไป:

from multiprocessing import Process
from matplotlib.pyplot import plot, show

def plot_graph(*args):
    for data in args:
        plot(data)
    show()

p = Process(target=plot_graph, args=([1, 2, 3],))
p.start()

print 'yay'
print 'computation continues...'
print 'that rocks.'

print 'Now lets wait for the graph be closed to continue...:'
p.join()

ที่มีค่าใช้จ่ายของการเปิดตัวกระบวนการใหม่และบางครั้งก็ยากที่จะแก้ปัญหาในสถานการณ์ที่ซับซ้อนดังนั้นฉันต้องการการแก้ปัญหาอื่น ๆ (ใช้matplotlib's nonblocking เรียก API )


ขอบคุณ! เนื่องจากฉันยังไม่มี Python 2.6 อยู่ในระบบของฉันฉันจึงใช้เธรดเธรดแทน Process ฉันสังเกตว่าคำสั่งการพิมพ์ที่ตามมาช้าเกินไปเหลือเกิน (พิมพ์ครั้งที่สามฉันออก KeyboardInterrupt หลังจากรอ 1 นาที) นี่เป็นผลของการใช้เธรดแทนการประมวลผลหลายตัวหรือไม่?
meteore

@meteore: ใช่เธรดดูด คุณสามารถรับมัลติโพรเซสซิ่ง
nosklo

มันยอดเยี่ยมจริงๆ คุณมีความคิดว่าทำไมคำสั่งการพิมพ์จะไม่ถูกดำเนินการเมื่ออยู่ใน Emacs (โหมดหลาม) จนกว่าจะปิดหน้าต่างพล็อต?
meteore

ใน Ubuntu 8.10 (Intrepid) แพ็คเกจ (สำหรับ python <2.6) เรียกว่า python-processing และคุณนำเข้ามันด้วย 'import processing'
meteore

1
คุณไม่พลาดif __name__ == '__main__':?
Wernight

25

ลอง

import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.show(block=False)
# other code
# [...]

# Put
plt.show()
# at the very end of your script to make sure Python doesn't bail out
# before you finished examining.

show()เอกสารพูดว่า:

ในโหมดที่ไม่โต้ตอบแสดงตัวเลขและบล็อกทั้งหมดจนกว่าตัวเลขจะถูกปิด ในโหมดอินเทอร์แอคทีฟจะไม่มีผลจนกว่าจะมีการสร้างตัวเลขก่อนการเปลี่ยนแปลงจากโหมดที่ไม่ต้องมีการโต้ตอบเป็นแบบอินเทอร์แอคทีฟ ในกรณีนั้นมันจะแสดงตัวเลข แต่ไม่ได้บล็อก

อาจมีการตั้งค่าอาร์กิวเมนต์คำหลักทดสอบหนึ่งบล็อกเป็นจริงหรือเท็จเพื่อแทนที่พฤติกรรมการปิดกั้นที่อธิบายไว้ข้างต้น


ทำไมไม่ใช้ draw (); [.other code]; แสดง ()? เท่าที่ฉันทราบ block = False เลิกใช้แล้ว
Bogdan

ทำไมคุณคิดว่าเลิกใช้แล้ว ฉันเห็นมันเอกสารที่นี่
Nico Schlömer

11

สำคัญ : เพื่อทำให้บางสิ่งบางอย่างชัดเจน ฉันคิดว่าคำสั่งอยู่ใน.pyสคริปต์และสคริปต์นั้นถูกเรียกใช้เช่นpython script.pyจากคอนโซล

วิธีง่ายๆที่เหมาะกับฉันคือ:

  1. ใช้บล็อก = เท็จภายในแสดง: plt.show (block = False)
  2. ใช้การแสดงอื่น () ที่ท้ายสคริปต์. py

ตัวอย่าง script.pyไฟล์:

plt.imshow(*something*)                                                               
plt.colorbar()                                                                             
plt.xlabel("true ")                                                                   
plt.ylabel("predicted ")                                                              
plt.title(" the matrix")  

# Add block = False                                           
plt.show(block = False)

################################
# OTHER CALCULATIONS AND CODE HERE ! ! !
################################

# the next command is the last line of my script
plt.show()



8

ในกรณีของฉันฉันต้องการให้มีหน้าต่างหลายอันโผล่ขึ้นมาขณะที่พวกเขากำลังคำนวณ สำหรับการอ้างอิงนี่คือวิธี:

from matplotlib.pyplot import draw, figure, show
f1, f2 = figure(), figure()
af1 = f1.add_subplot(111)
af2 = f2.add_subplot(111)
af1.plot([1,2,3])
af2.plot([6,5,4])
draw() 
print 'continuing computation'
show()

PS ที่มีประโยชน์ค่อนข้างคู่มืออินเตอร์เฟซ OO matplotlib ของ


6

ฉันมีปัญหาอย่างมากในการหาคำสั่งที่ไม่มีการปิดกั้น ... แต่ในที่สุดฉันก็สามารถทำซ้ำ " Cookbook / Matplotlib / ภาพเคลื่อนไหว - สร้างภาพเคลื่อนไหวองค์ประกอบของพล็อตที่เลือก " ดังนั้นจึงทำงานกับเธรด ( และส่งผ่านข้อมูลระหว่างเธรด ผ่านตัวแปรทั่วโลกหรือผ่านหลายกระบวนการPipe ) บน Python 2.6.5 บน Ubuntu 10.04

สคริปต์สามารถพบได้ที่นี่: Animating_selected_plot_elements-thread.py - วางไว้ด้านล่าง ( มีความคิดเห็นน้อยกว่า ) เพื่อการอ้างอิง:

import sys
import gtk, gobject
import matplotlib
matplotlib.use('GTKAgg')
import pylab as p
import numpy as nx 
import time

import threading 



ax = p.subplot(111)
canvas = ax.figure.canvas

# for profiling
tstart = time.time()

# create the initial line
x = nx.arange(0,2*nx.pi,0.01)
line, = ax.plot(x, nx.sin(x), animated=True)

# save the clean slate background -- everything but the animated line
# is drawn and saved in the pixel buffer background
background = canvas.copy_from_bbox(ax.bbox)


# just a plain global var to pass data (from main, to plot update thread)
global mypass

# http://docs.python.org/library/multiprocessing.html#pipes-and-queues
from multiprocessing import Pipe
global pipe1main, pipe1upd
pipe1main, pipe1upd = Pipe()


# the kind of processing we might want to do in a main() function,
# will now be done in a "main thread" - so it can run in
# parallel with gobject.idle_add(update_line)
def threadMainTest():
    global mypass
    global runthread
    global pipe1main

    print "tt"

    interncount = 1

    while runthread: 
        mypass += 1
        if mypass > 100: # start "speeding up" animation, only after 100 counts have passed
            interncount *= 1.03
        pipe1main.send(interncount)
        time.sleep(0.01)
    return


# main plot / GUI update
def update_line(*args):
    global mypass
    global t0
    global runthread
    global pipe1upd

    if not runthread:
        return False 

    if pipe1upd.poll(): # check first if there is anything to receive
        myinterncount = pipe1upd.recv()

    update_line.cnt = mypass

    # restore the clean slate background
    canvas.restore_region(background)
    # update the data
    line.set_ydata(nx.sin(x+(update_line.cnt+myinterncount)/10.0))
    # just draw the animated artist
    ax.draw_artist(line)
    # just redraw the axes rectangle
    canvas.blit(ax.bbox)

    if update_line.cnt>=500:
        # print the timing info and quit
        print 'FPS:' , update_line.cnt/(time.time()-tstart)

        runthread=0
        t0.join(1)   
        print "exiting"
        sys.exit(0)

    return True



global runthread

update_line.cnt = 0
mypass = 0

runthread=1

gobject.idle_add(update_line)

global t0
t0 = threading.Thread(target=threadMainTest)
t0.start() 

# start the graphics update thread
p.show()

print "out" # will never print - show() blocks indefinitely! 

หวังว่านี่จะช่วยใครซักคน
ไชโย!


5

ในหลายกรณีจะสะดวกกว่าก่อนที่จะบันทึกภาพเป็นไฟล์. png ในฮาร์ดไดรฟ์ นี่คือเหตุผล:

ข้อดี:

  • คุณสามารถเปิดดูได้และปิดมันได้ตลอดเวลาในกระบวนการ สะดวกยิ่งขึ้นเมื่อแอปพลิเคชันของคุณทำงานเป็นเวลานาน
  • ไม่มีสิ่งใดปรากฏขึ้นและคุณไม่ได้ถูกบังคับให้เปิดหน้าต่าง สิ่งนี้จะสะดวกเป็นพิเศษเมื่อคุณต้องรับมือกับตัวเลขมากมาย
  • ภาพของคุณสามารถเข้าถึงได้สำหรับการอ้างอิงในภายหลังและจะไม่สูญหายเมื่อปิดหน้าต่างรูป

ข้อเสียเปรียบ

  • สิ่งเดียวที่ฉันคิดได้ก็คือคุณจะต้องค้นหาโฟลเดอร์และเปิดภาพด้วยตัวคุณเอง

หากคุณกำลังพยายามสร้างภาพจำนวนมากฉันเห็นด้วยอย่างเต็มที่
fantabolous

6
png ที่ดึงกลับมานั้นไม่ได้มีการโต้ตอบ: \
Inverse

5

หากคุณกำลังทำงานในคอนโซลนั่นคือIPythonคุณสามารถใช้plt.show(block=False)ตามที่ระบุไว้ในคำตอบอื่น ๆ แต่ถ้าคุณขี้เกียจคุณก็สามารถพิมพ์:

plt.show(0)

ซึ่งจะเหมือนกัน


5

ฉันต้องเพิ่มplt.pause(0.001)รหัสของฉันเพื่อให้มันทำงานในวง for (ไม่เช่นนั้นจะแสดงเฉพาะพล็อตแรกและสุดท้าย):

import matplotlib.pyplot as plt

plt.scatter([0], [1])
plt.draw()
plt.show(block=False)

for i in range(10):
    plt.scatter([i], [i+1])
    plt.draw()
    plt.pause(0.001)

สิ่งนี้ใช้ได้กับฉันด้วย matplotlib3 บน macOS ที่ดี!
Jerry Ma

4

ในระบบของฉันแสดง () ไม่ได้ปิดกั้นแม้ว่าฉันต้องการให้สคริปต์รอให้ผู้ใช้โต้ตอบกับกราฟ (และรวบรวมข้อมูลโดยใช้การเรียกกลับ 'pick_event') ก่อนดำเนินการต่อ

เพื่อปิดกั้นการดำเนินการจนกว่าจะปิดหน้าต่างการลงจุดฉันใช้สิ่งต่อไปนี้:

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.plot(x,y)

# set processing to continue when window closed
def onclose(event):
    fig.canvas.stop_event_loop()
fig.canvas.mpl_connect('close_event', onclose)

fig.show() # this call does not block on my system
fig.canvas.start_event_loop_default() # block here until window closed

# continue with further processing, perhaps using result from callbacks

หมายเหตุอย่างไรก็ตาม canvas.start_event_loop_default () นั้นได้สร้างคำเตือนดังต่อไปนี้:

C:\Python26\lib\site-packages\matplotlib\backend_bases.py:2051: DeprecationWarning: Using default event loop until function specific to this GUI is implemented
  warnings.warn(str,DeprecationWarning)

แม้ว่าสคริปต์ยังคงทำงานอยู่


ขอบคุณ! Spyder นำเข้า -pylab เมื่อเริ่มต้นซึ่งโดยทั่วไปมีประโยชน์ แต่หมายความว่า show () จะไม่ปิดกั้นเมื่อ ioff () - สิ่งนี้ช่วยให้คุณสามารถแก้ไขพฤติกรรมนี้!
แพ้

3

ฉันยังต้องการให้พล็อตของฉันแสดงผลเรียกใช้ส่วนที่เหลือของรหัส (จากนั้นแสดงต่อไป) แม้ว่าจะมีข้อผิดพลาด (บางครั้งฉันใช้พล็อตสำหรับการดีบัก) ฉันเขียนรหัสแฮ็กน้อยนี้เพื่อให้แปลงใด ๆ ในwithคำสั่งนี้มีพฤติกรรมเช่นนี้

นี่อาจเป็นบิตที่ไม่ได้มาตรฐานเกินไปและไม่แนะนำสำหรับรหัสการผลิต อาจมี "gotchas" ที่ซ่อนอยู่จำนวนมากในรหัสนี้

from contextlib import contextmanager

@contextmanager
def keep_plots_open(keep_show_open_on_exit=True, even_when_error=True):
    '''
    To continue excecuting code when plt.show() is called
    and keep the plot on displaying before this contex manager exits
    (even if an error caused the exit).
    '''
    import matplotlib.pyplot
    show_original = matplotlib.pyplot.show
    def show_replacement(*args, **kwargs):
        kwargs['block'] = False
        show_original(*args, **kwargs)
    matplotlib.pyplot.show = show_replacement

    pylab_exists = True
    try:
        import pylab
    except ImportError: 
        pylab_exists = False
    if pylab_exists:
        pylab.show = show_replacement

    try:
        yield
    except Exception, err:
        if keep_show_open_on_exit and even_when_error:
            print "*********************************************"
            print "Error early edition while waiting for show():" 
            print "*********************************************"
            import traceback
            print traceback.format_exc()
            show_original()
            print "*********************************************"
            raise
    finally:
        matplotlib.pyplot.show = show_original
        if pylab_exists:
            pylab.show = show_original
    if keep_show_open_on_exit:
        show_original()

# ***********************
# Running example
# ***********************
import pylab as pl
import time
if __name__ == '__main__':
    with keep_plots_open():
        pl.figure('a')
        pl.plot([1,2,3], [4,5,6])     
        pl.plot([3,2,1], [4,5,6])
        pl.show()

        pl.figure('b')
        pl.plot([1,2,3], [4,5,6])
        pl.show()

        time.sleep(1)
        print '...'
        time.sleep(1)
        print '...'
        time.sleep(1)
        print '...'
        this_will_surely_cause_an_error

หาก / เมื่อฉันใช้งานที่เหมาะสม "เปิดแปลง (แม้ว่าจะมีข้อผิดพลาดเกิดขึ้น) และอนุญาตให้แปลงใหม่แสดง" ฉันต้องการสคริปต์ให้ออกอย่างถูกต้องหากไม่มีการแทรกแซงของผู้ใช้บอกเป็นอย่างอื่น

ฉันอาจใช้คำถามแบบหมดเวลา "End of script! \ n กด p หากคุณต้องการให้พล็อตการแสดงผลถูกหยุดชั่วคราว (คุณมี 5 วินาที):" จาก/programming/26704840/corner -cases


2
plt.figure(1)
plt.imshow(your_first_image)

plt.figure(2)
plt.imshow(your_second_image)

plt.show(block=False) # That's important 

raw_input("Press ENTER to exist") # Useful when you run your Python script from the terminal and you want to hold the running to see your figures until you press Enter

16
วิธีกดหนึ่งจะป้อนก่อนที่มีอยู่?
grovina

2

OP ถามเกี่ยวกับการแยกmatplotlibแปลง คำตอบส่วนใหญ่ถือว่าคำสั่งดำเนินการจากภายในล่ามหลาม กรณีใช้งานที่นำเสนอในที่นี้คือค่ากำหนดของฉันสำหรับการทดสอบโค้ดในเทอร์มินัล (เช่นทุบตี) ที่มีการfile.pyรันและคุณต้องการให้พล็อตเกิดขึ้น แต่สคริปต์ python จะทำงานให้เสร็จสมบูรณ์

ไฟล์แบบสแตนด์อะโลนนี้ใช้เพื่อเปิดเป็นกระบวนการที่แยกต่างหากสำหรับข้อมูลที่มีพล็อตmultiprocessing matplotlibเธรดหลักออกจากการใช้ที่os._exit(1)กล่าวถึงในนี้โพสต์ os._exit()กองกำลังหลักเพื่อออก แต่ใบmatplotlibกระบวนการเด็กยังมีชีวิตอยู่และตอบสนองจนกว่าหน้าต่างพล็อตจะปิด มันเป็นกระบวนการที่แยกจากกันโดยสิ้นเชิง

วิธีนี้เปรียบเสมือนเซสชั่นการพัฒนา Matlab ที่มีหน้าต่างตัวเลขที่มาพร้อมกับพรอมต์คำสั่งที่ตอบสนองได้ ด้วยวิธีการนี้คุณสูญเสียการติดต่อกับกระบวนการหน้าต่างตัวเลขทั้งหมด แต่ก็ไม่เป็นไรสำหรับการพัฒนาและการดีบัก เพียงปิดหน้าต่างและทำการทดสอบต่อไป

multiprocessingsubprocessถูกออกแบบมาสำหรับการเรียกใช้รหัสหลามเท่านั้นซึ่งจะทำให้มันอาจจะเหมาะดีกว่า multiprocessingข้ามแพลตฟอร์มดังนั้นสิ่งนี้จะทำงานได้ดีใน Windows หรือ Mac โดยมีการปรับเพียงเล็กน้อยหรือไม่มีเลย ไม่จำเป็นต้องตรวจสอบระบบปฏิบัติการพื้นฐาน นี่คือการทดสอบบน linux, Ubuntu 18.04LTS

#!/usr/bin/python3

import time
import multiprocessing
import os

def plot_graph(data):
    from matplotlib.pyplot import plot, draw, show
    print("entered plot_graph()")
    plot(data)
    show() # this will block and remain a viable process as long as the figure window is open
    print("exiting plot_graph() process")

if __name__ == "__main__":
    print("starting __main__")
    multiprocessing.Process(target=plot_graph, args=([1, 2, 3],)).start()
    time.sleep(5)
    print("exiting main")
    os._exit(0) # this exits immediately with no cleanup or buffer flushing

การเปิดใช้file.pyจะปรากฏหน้าต่างรูปขึ้นมาจากนั้นจึง__main__ออก แต่multiprocessing+matplotlibหน้าต่างรูปยังคงตอบสนองต่อการซูมแพนและปุ่มอื่น ๆ เนื่องจากเป็นกระบวนการที่เป็นอิสระ

ตรวจสอบกระบวนการที่พร้อมท์คำสั่ง bash ด้วย:

ps ax|grep -v grep |grep file.py


ฉันพยายามใช้โซลูชันของคุณ แต่ดูเหมือนจะไม่เหมาะกับฉันและฉันพยายามหาสาเหตุ ฉันไม่ได้เรียกใช้รหัสผ่านเทอร์มินัล แต่มาจาก Pycharm IDE หากนั่นสร้างความแตกต่างแม้ว่ามันจะไม่ควร
ttsesm

1
ตกลงสิ่งที่ได้ผลในที่สุดสำหรับฉันคือการตั้งค่ากระบวนการเด็กด้วย.daemon=Falseตามที่อธิบายไว้ที่นี่stackoverflow.com/a/49607287/1476932อย่างไรก็ตามsys.exit()ไม่ได้ยกเลิกกระบวนการหลักตามที่อธิบายไว้ที่นั่นจนกว่าฉันจะปิดหน้าต่างลูก ในทางกลับกันการใช้os._exit(0)จากตัวอย่างข้างต้นได้ผล
ttsesm

1

ในความคิดของฉันคำตอบในหัวข้อนี้ให้วิธีการที่ไม่สามารถใช้ได้กับทุกระบบและในสถานการณ์ที่ซับซ้อนเช่นภาพเคลื่อนไหว ฉันขอแนะนำให้ดูที่คำตอบของ MiKTeX ในเธรดต่อไปนี้ซึ่งพบวิธีการที่แข็งแกร่ง: วิธีการรอจนกว่า matplotlib แอนิเมชันจะสิ้นสุดลง?


0

หากคุณต้องการเปิดตัวเลขหลายตัวในขณะที่ยังคงเปิดอยู่ทั้งหมดรหัสนี้ใช้ได้กับฉัน:

show(block=False)
draw()

show (block = False) เลิกใช้แล้วและตอนนี้ไม่สามารถใช้งานได้อีกแล้ว
Bogdan

0

ในขณะที่ไม่ตอบคำขอ OPs โดยตรงฉันโพสต์การแก้ปัญหานี้เพราะอาจช่วยคนในสถานการณ์นี้:

  • ฉันกำลังสร้าง. exe ด้วย pyinstaller เนื่องจากฉันไม่สามารถติดตั้งไพ ธ อนที่ฉันต้องการสร้างพล็อตดังนั้นฉันต้องใช้สคริปต์ไพ ธ อนเพื่อสร้างพล็อตบันทึกเป็น. png ปิดมันและดำเนินการถัดไป ห่วงหรือใช้ฟังก์ชั่น

สำหรับ Im นี้โดยใช้:

import matplotlib.pyplot as plt
#code generating the plot in a loop or function
#saving the plot
plt.savefig(var+'_plot.png',bbox_inches='tight', dpi=250) 
#you can allways reopen the plot using
os.system(var+'_plot.png') # unfortunately .png allows no interaction.
#the following avoids plot blocking the execution while in non-interactive mode
plt.show(block=False) 
#and the following closes the plot while next iteration will generate new instance.
plt.close() 

โดยที่ "var" ระบุพล็อตในลูปดังนั้นจึงไม่ถูกเขียนทับ


-1

การใช้งานและในตอนท้ายของการโทรสคริปต์ของคุณplt.show(block=False)plt.show()

สิ่งนี้จะช่วยให้มั่นใจว่าหน้าต่างจะไม่ถูกปิดเมื่อสคริปต์เสร็จสิ้น


ดูคำตอบของ @ nico-schlömer
Josh Wolff
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.