เรียกใช้ pylab.savefig โดยไม่แสดงผลใน ipython


112

ฉันต้องการสร้างรูปในไฟล์โดยไม่ต้องแสดงในสมุดบันทึก IPython ฉันไม่ชัดเจนเกี่ยวกับปฏิสัมพันธ์ระหว่างIPythonและmatplotlib.pylabในเรื่องนี้ แต่เมื่อฉันเรียกpylab.savefig("test.png")ตัวเลขปัจจุบันได้รับการแสดงนอกเหนือจากการบันทึกในtest.png. เมื่อสร้างไฟล์พล็อตชุดใหญ่โดยอัตโนมัติสิ่งนี้มักไม่เป็นที่พึงปรารถนา หรือในสถานการณ์ที่ต้องการไฟล์กลางสำหรับการประมวลผลภายนอกโดยแอปอื่น

ไม่แน่ใจว่าเป็นคำถามmatplotlibหรือIPythonสมุดบันทึก


คำตอบโดย @staticfloat ใช้ได้กับฉันแม้ว่าจะไม่ได้อยู่ในโน้ตบุ๊กก็ตามและเมื่อใช้ matplotlib ผ่าน JuliaLang ใช้ioff
Vass

คำตอบ:


173

นี่เป็นคำถาม matplotlib และคุณสามารถแก้ไขปัญหานี้ได้โดยใช้แบ็กเอนด์ที่ไม่แสดงต่อผู้ใช้เช่น 'Agg':

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

plt.plot([1,2,3])
plt.savefig('/tmp/test.png')

แก้ไข:หากคุณไม่ต้องการสูญเสียความสามารถในการแสดงพล็อตให้ปิดโหมดโต้ตอบและโทรplt.show()เมื่อคุณพร้อมที่จะแสดงพล็อตเท่านั้น:

import matplotlib.pyplot as plt

# Turn interactive plotting off
plt.ioff()

# Create a new figure, plot into it, then close it so it never gets displayed
fig = plt.figure()
plt.plot([1,2,3])
plt.savefig('/tmp/test0.png')
plt.close(fig)

# Create a new figure, plot into it, then don't close it so it does get displayed
plt.figure()
plt.plot([1,3,2])
plt.savefig('/tmp/test1.png')

# Display all "open" (non-closed) figures
plt.show()

2
โอเค - แต่โดยทั่วไปฉันต้องการคงการวางแผนแบบอินไลน์ไว้ใน iPython สิ่งที่คุณแนะนำจะใช้ได้ดีหากทำการสลับที่แบ็กเอนด์อย่างสมบูรณ์ คำถามคือคุณจะอนุญาตให้เกิดสถานการณ์ทั่วไปของการพล็อตแบบอินไลน์กับกรณีพิเศษของตัวเลขการออมได้อย่างไร (โดยไม่ต้องแสดงอินไลน์) ตามคำแนะนำของคุณฉันพยายามโหลดโมดูลใหม่และเปลี่ยนแบ็กเอนด์ชั่วคราว แต่ไม่สำเร็จ มีแนวคิดเกี่ยวกับวิธีเปลี่ยนแบ็กเอนด์ชั่วคราวภายในเซสชันโน้ตบุ๊ก iPython หรือไม่?
tnt

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

3
ขอบคุณสำหรับคำติชมที่ดีเยี่ยม ดูเหมือนว่า plt.close (fig) เป็นคำสั่งสำคัญสำหรับความต้องการของฉัน ฉันยังไม่ชัดเจนเกี่ยวกับ ioff เนื่องจากดูเหมือนจะไม่ส่งผลกระทบต่อการดำเนินการ แต่ฉันอาจจะขาดอะไรไป ขอบคุณอีกครั้ง.
tnt

1
สูตรที่ฉันให้เป็นสูตรทั่วไป หากคุณไม่ได้ทำงานในโน้ตบุ๊ก ipython plt.ioff () เป็นสิ่งสำคัญในการหยุดตัวเลขจากการกะพริบในและนอกหน้าจอเนื่องจากตัวเลข ipython ในบรรทัดคำสั่งจะถูกพล็อตทันทีที่คุณโทรplt.plot()หากเปิดโหมดโต้ตอบ เปิดโหมดโต้ตอบปิดความล่าช้าในการแสดงผลของการแปลงใด ๆ plt.show()จนกว่าจะมีการ เนื่องจากคุณใช้โน้ตบุ๊ก ipython โหมดโต้ตอบจึงได้รับการปฏิบัติที่แตกต่างกัน
staticfloat

สำหรับฉันmatplotlib.use('Agg')คนเดียวทำเคล็ดลับ ฉันไม่ต้องการรหัสใด ๆplt.show()หรือplt.ioff()ในรหัสของฉันเลย
Zhanwen Chen

67

เราไม่จำเป็นต้องplt.ioff()หรือplt.show()(ถ้าเราใช้%matplotlib inline) plt.ioff()คุณสามารถทดสอบรหัสข้างต้นโดยไม่ต้อง plt.close()มีบทบาทสำคัญ ลองอันนี้:

%matplotlib inline
import pylab as plt

# It doesn't matter you add line below. You can even replace it by 'plt.ion()', but you will see no changes.
## plt.ioff()

# Create a new figure, plot into it, then close it so it never gets displayed
fig = plt.figure()
plt.plot([1,2,3])
plt.savefig('test0.png')
plt.close(fig)

# Create a new figure, plot into it, then don't close it so it does get displayed
fig2 = plt.figure()
plt.plot([1,3,2])
plt.savefig('test1.png')

หากคุณรันโค้ดนี้ใน iPython โค้ดจะแสดงพล็อตที่สองและหากคุณเพิ่มลง plt.close(fig2)ไปในตอนท้ายคุณจะไม่เห็นอะไรเลย

สรุปได้ว่าถ้าคุณปิดตัวเลขplt.close(fig)มันจะไม่แสดง


5
ทางออกที่ดีกว่าแน่นอน! ฉันสร้างและบันทึกหลายแปลงในวง ด้วยความที่ฉันได้รับplt.ioff แก้ไขได้ RuntimeWarning: More than 20 figures have been opened...plt.close
Nagasaki45
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.