บันทึกภาพด้วย python ด้วยคุณภาพที่สูงมาก


110

ฉันจะบันทึกพล็อต python ที่มีคุณภาพสูงได้อย่างไร

นั่นคือเมื่อฉันซูมเข้าวัตถุที่บันทึกในไฟล์ pdf ไปเรื่อย ๆ ไม่มีการเบลอ?

นอกจากนี้โหมดที่ดีที่สุดในการบันทึกคืออะไร?

png, eps? หรืออื่น ๆ ? ฉันทำไม่ได้pdfเพราะมีตัวเลขที่ซ่อนอยู่ซึ่งเกิดขึ้นกับการLatexmkรวบรวม

คำตอบ:


153

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

plt.savefig('destination_path.eps', format='eps')

ฉันพบว่าไฟล์ eps ทำงานได้ดีที่สุดและdpiพารามิเตอร์คือสิ่งที่ทำให้พวกเขาดูดีในเอกสาร

อัพเดท:

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

ax.view_init(elev=elevation_angle, azim=azimuthal_angle)

ที่ไหน elevation_angleตัวเลข (เป็นองศา) ระบุมุมเชิงขั้ว (ลงจากแกน z แนวตั้ง)ระบุมุมราบazimuthal_angle(รอบแกน z)

ฉันพบว่ามันง่ายที่สุดในการกำหนดค่าเหล่านี้โดยการพล็อตภาพก่อนแล้วหมุนและดูค่าปัจจุบันของมุมที่ปรากฏทางด้านล่างของหน้าต่างด้านล่างพล็อตจริง โปรดทราบว่าตำแหน่ง x, y, z จะปรากฏตามค่าเริ่มต้น แต่จะถูกแทนที่ด้วยมุมทั้งสองเมื่อคุณเริ่มคลิก + ลาก + หมุนรูปภาพ


@ spencerlon2 จะเป็นอย่างไรหากต้องการเปลี่ยนแนวของรูปก่อนบันทึก
dustin

13
ทำไมเราถึงต้องการพารามิเตอร์ DPI eps ไม่ใช่รูปแบบเวกเตอร์หรือไม่?
mkvoya

1
จุดดี - ไม่จำเป็นต้องใช้ DPI สำหรับรูปแบบเวกเตอร์เช่น svg, pdf, eps
spencerlyon2

คุณสามารถละเว้นได้format='eps'หากต้องการ ในกรณีนี้รูปแบบจะอนุมานจากชื่อไฟล์
timgeb

72

เพียงแค่เพิ่มผลลัพธ์ของฉันโดยใช้ matplotlib

.eps ทำให้ข้อความทั้งหมดของฉันเป็นตัวหนาและลบความโปร่งใส .svg ให้รูปภาพความละเอียดสูงที่ดูเหมือนกราฟของฉันจริงๆ

import matplotlib.pyplot as plt
fig, ax = plt.subplots()
# Do the plot code
fig.savefig('myimage.svg', format='svg', dpi=1200)

ฉันใช้ 1200 dpi เนื่องจากวารสารทางวิทยาศาสตร์จำนวนมากต้องการภาพที่ 1200/600 / 300 dpi ขึ้นอยู่กับว่าภาพนั้นเป็นอย่างไร แปลงเป็น dpi และฟอร์แมตที่ต้องการใน GiMP หรือ Inkscape

แก้ไข: เห็นได้ชัดว่า dpi ไม่สำคัญเนื่องจาก. svg เป็นกราฟิกแบบเวกเตอร์และมี "ความละเอียดไม่สิ้นสุด"


2
DPI มีความสำคัญอย่างมากเมื่อเราใช้imshow(..)ที่ไหนสักแห่งในรูป บิตแมปเหล่านี้จะถูกแรสเตอร์ลงเมื่อฝังลงใน SVG ด้วย DPI เริ่มต้นผลลัพธ์จะแย่กว่าที่เราเห็นบนหน้าจอซึ่งไม่เหมาะสำหรับสิ่งพิมพ์
Evgeni Sergeev

ฉันขอแนะนำให้ใช้ Scour ( github.com/scour-project/scour ) เพื่อลดขนาดไฟล์ของ svg ของคุณ ในการตั้งค่าที่ก้าวร้าวที่สุดฉันสามารถลดขนาดไฟล์ของฉันเป็น 50% ของต้นฉบับ - 5% ถ้าฉันใช้รูปแบบบีบอัด. svgz
grofte

8

โอเคฉันพบว่าคำตอบของ spencerlyon2 ใช้งานได้ แต่ในกรณีที่ใครก็ตามพบว่าตัวเองไม่รู้ว่าจะทำอย่างไรกับบรรทัดเดียวฉันต้องทำแบบนี้:

beingsaved = plt.figure()

# some scatters
plt.scatter(X_1_x, X_1_y)
plt.scatter(X_2_x, X_2_y)

beingsaved.savefig('destination_path.eps', format='eps', dpi=1000)

7

ในกรณีที่คุณกำลังทำงานกับนกทะเลแปลงแทนการ matplotlib คุณสามารถบันทึกภาพ .png เช่นนี้

สมมติว่าคุณมีmatrixวัตถุ (ไม่ว่าจะเป็นแพนด้าหรือตัวเลข) และคุณต้องการใช้แผนที่ความร้อน:

import seaborn as sb

image = sb.heatmap(matrix)   # this gets you the heatmap
image.figure.savefig("C:/Your/Path/ ... /your_image.png")   # this saves it

รหัสนี้เข้ากันได้กับซีบอร์นเวอร์ชันล่าสุด รหัสอื่น ๆ รอบ ๆ stackoverflow ใช้งานได้กับเวอร์ชันก่อนหน้าเท่านั้น

อีกวิธีหนึ่งที่ฉันชอบคือสิ่งนี้ ฉันกำหนดขนาดของภาพถัดไปดังนี้:

plt.subplots(figsize=(15,15))

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


5

คุณสามารถบันทึกเป็นรูปที่ 1920x1080 (หรือ 1080p) โดยใช้:

fig = plt.figure(figsize=(19.20,10.80))

คุณยังสามารถไปได้สูงหรือต่ำกว่ามาก วิธีแก้ปัญหาข้างต้นทำงานได้ดีสำหรับการพิมพ์ แต่ทุกวันนี้คุณต้องการให้ภาพที่สร้างขึ้นเป็น PNG / JPG หรือปรากฏในรูปแบบหน้าจอกว้าง

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