การลบพื้นที่สีขาวรอบรูปภาพที่บันทึกใน matplotlib


172

ฉันต้องการถ่ายภาพและบันทึกหลังจากกระบวนการบางอย่าง รูปดูดีเมื่อฉันแสดง แต่หลังจากบันทึกตัวเลขฉันมีพื้นที่สีขาวรอบรูปภาพที่บันทึกไว้ ฉันได้ลองใช้'tight'ตัวเลือกสำหรับsavefigวิธีการแล้วก็ไม่ได้ผล รหัส:

  import matplotlib.image as mpimg
  import matplotlib.pyplot as plt

  fig = plt.figure(1)
  img = mpimg.imread(path)
  plt.imshow(img)
  ax=fig.add_subplot(1,1,1)

  extent = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
  plt.savefig('1.png', bbox_inches=extent)

  plt.axis('off') 
  plt.show()

ฉันกำลังพยายามวาดกราฟพื้นฐานโดยใช้ NetworkX ในรูปและบันทึก ฉันรู้ว่าไม่มีกราฟมันทำงาน แต่เมื่อเพิ่มกราฟฉันได้รับพื้นที่สีขาวรอบภาพที่บันทึกไว้;

import matplotlib.image as mpimg
import matplotlib.pyplot as plt
import networkx as nx

G = nx.Graph()
G.add_node(1)
G.add_node(2)
G.add_node(3)
G.add_edge(1,3)
G.add_edge(1,2)
pos = {1:[100,120], 2:[200,300], 3:[50,75]}

fig = plt.figure(1)
img = mpimg.imread("C:\\images\\1.jpg")
plt.imshow(img)
ax=fig.add_subplot(1,1,1)

nx.draw(G, pos=pos)

extent = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
plt.savefig('1.png', bbox_inches = extent)

plt.axis('off') 
plt.show()

1
สำเนาซ้ำที่เป็นไปได้ของการบันทึกรูป matplotlib / networkx โดยไม่มีระยะขอบ
Joel

สิ่งที่ได้ผลจริงๆสำหรับฉันคือการครอบตัด pdf โดยใช้เครื่องมืออื่นเช่น pdfcrop
toliveira

คำตอบ:


170

ฉันไม่สามารถอ้างสิทธิ์ได้ว่าฉันรู้สาเหตุหรือวิธีการ“ แก้ไขปัญหา” ของฉันอย่างไร แต่นี่คือสิ่งที่ฉันต้องทำเมื่อฉันต้องการพล็อตโครงร่างของส่วน aerofoil สองส่วนโดยไม่มีระยะขอบสีขาวเป็นไฟล์ PDF (โปรดทราบว่าฉันใช้ matplotlib ในสมุดบันทึก IPython พร้อมกับแฟล็ก -pylab)

plt.gca().set_axis_off()
plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, 
            hspace = 0, wspace = 0)
plt.margins(0,0)
plt.gca().xaxis.set_major_locator(plt.NullLocator())
plt.gca().yaxis.set_major_locator(plt.NullLocator())
plt.savefig("filename.pdf", bbox_inches = 'tight',
    pad_inches = 0)

ฉันได้พยายามที่จะปิดการใช้งานส่วนต่าง ๆ ของนี้ แต่นี้มักจะนำไปสู่การขอบสีขาวบางแห่ง คุณอาจปรับเปลี่ยนสิ่งนี้เพื่อรักษาเส้นไขมันใกล้กับขีด จำกัด ของตัวเลขจากการถูกโกนเนื่องจากการขาดระยะขอบ


6
ในที่สุดสิ่งที่ใช้งานได้ขอบคุณมาก! ในกรณีของฉันมีเพียงสองบรรทัดset_major_locatorเท่านั้นที่จำเป็น
Florian Brucker

6
ฉันใช้เวลาชั่วโมงสุดท้ายในการลองสิ่งต่าง ๆ และไม่สามารถกำจัดเส้นขอบสีขาวขนาด 1px ได้ นี่เป็นสิ่งเดียวที่ทำงานได้โดยเฉพาะpad_inches=0คำตอบที่ไม่ได้กล่าวถึง
AnnanFay

1
set_major_locatorเป็นกุญแจสำคัญสำหรับฉัน
kmac

16
pad_inchesช่วยฉัน
Myles Baker

5
matplotlib.ticker.NullLocator ()
Joop

200

คุณสามารถลบช่องว่างภายในโดยการตั้งค่าbbox_inches="tight"ในsavefig:

plt.savefig("test.png",bbox_inches='tight')

คุณจะต้องใส่อาร์กิวเมนต์bbox_inchesเป็นสตริงบางทีนี่อาจเป็นเหตุผลว่าทำไมมันถึงไม่ได้ผลสำหรับคุณ


ข้อมูลซ้ำที่เป็นไปได้:

Matplotlib แปลง: ลบแกนตำนานและช่องว่างสีขาว

วิธีการตั้งค่าระยะขอบสำหรับรูป matplotlib?

ลดระยะขอบซ้ายและขวาในพล็อต matplotlib


1
หากคุณมีหลาย subplots และต้องการบันทึกแต่ละอันคุณสามารถใช้มันได้fig.savefig()เช่นกัน ( plt.savefig()จะไม่ทำงานในกรณีนั้น)
Abhranil Das

30
ที่ไม่ค่อนข้างขวา เมื่อคุณใช้bbox_inchesตัวเลือกนั้นจะมีค่าเริ่มต้นอื่นที่เหลือพื้นที่ว่าง หากคุณต้องการกำจัดทุกสิ่งจริงๆคุณต้องใช้pad_inches=0.0ด้วย แน่นอนว่าช่องว่างภายในที่แน่นหนาเช่นนี้มักจะถูกตัดออกเช่นเลขชี้กำลัง ...
Mike

5
หากต้องการลบขอบสีดำเช่นกันคุณอาจต้องตั้งค่าpad_inches=-0.1
lenhhoxung

10
สิ่งนี้ใช้ไม่ได้ผลคุณยังคงมีพื้นที่ว่างรอบร่าง การตั้งค่าตัวเลือกแบบโปร่งใส (ดังที่ได้กล่าวไว้ในคำตอบบางอย่าง) ไม่ได้ช่วยอะไรอย่างแท้จริงช่องว่างยังคงอยู่ที่นั่นมันเป็นแบบโปร่งใส
BjornW

1
@piperchester เป็นคำถามที่ดี แต่อาจจะถูกถามว่าเป็นคำถามใหม่ทั้งหมดดังนั้นจึงไม่ได้หายไปจากความคิดเห็น คุณควรเชื่อมโยงคำถามใหม่กับคำถามเก่า!
ติดยาเสพติด

21

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

plt.gca().set_axis_off()
plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, 
            hspace = 0, wspace = 0)
plt.margins(0,0)
plt.savefig("myfig.pdf")

ที่สำคัญสิ่งนี้ไม่รวมถึงอาร์กิวเมนต์ bbox หรือ padding


4
นี่ควรเป็นคำตอบที่ยอมรับได้ นอกจากนี้คุณไม่จำเป็นต้องโทรออกset_axis_offด้วยซ้ำ มันจะไม่ส่งผลกระทบต่อภาพที่บันทึกไว้หลังจากsubplots_adjustที่แกนอยู่นอกขอบเขตของตัวเลขและจะไม่ถูกลบออก อย่างไรก็ตามในสมุดบันทึก Jupyter คุณต้องปิดการใช้งานแกนอย่างชัดเจนเนื่องจากแบ็กเอนด์แบบอินไลน์เขียนทับการตั้งค่าเหล่านี้
MaxPowers

20

ฉันพบบางสิ่งจาก Arvind Pereira ( http://robotics.usc.edu/~ampereir/wordpress/?p=626 ) และดูเหมือนว่าจะทำงานให้ฉัน:

plt.savefig(filename, transparent = True, bbox_inches = 'tight', pad_inches = 0)

7
transparent=Trueจะทำให้ดูเหมือนไม่มีปัญหา แต่จะซ่อนพื้นที่สีขาวขนาดภาพจะไม่โอเค
Vlady Veselinov

ขอบคุณที่พูดถึงpad_inches! ฉันขอให้ฉันรู้จักตัวเลือกนี้ก่อนหน้านี้!
ingomueller.net

1
วิธีนี้ใช้ได้ผลกับแผนการส่วนใหญ่ แต่นี่เป็นการลบเส้นขอบที่เหมาะสมสำหรับเมทริกซ์ความสับสนของฉัน เพียงเพิ่มช่องว่างขนาดเล็กpad_inches=.25
YTZ

14

ฟังก์ชั่นต่อไปนี้รวมเอาคำตอบของโจฮันเนสไว้ด้านบน ฉันทดสอบด้วยplt.figureและplt.subplots()มีหลายแกนและทำงานได้ดี

def save(filepath, fig=None):
    '''Save the current image with no whitespace
    Example filepath: "myfig.png" or r"C:\myfig.pdf" 
    '''
    import matplotlib.pyplot as plt
    if not fig:
        fig = plt.gcf()

    plt.subplots_adjust(0,0,1,1,0,0)
    for ax in fig.axes:
        ax.axis('off')
        ax.margins(0,0)
        ax.xaxis.set_major_locator(plt.NullLocator())
        ax.yaxis.set_major_locator(plt.NullLocator())
    fig.savefig(filepath, pad_inches = 0, bbox_inches='tight')

ทำงานเหมือนจับใจ คำตอบก่อนหน้านี้คือคำสั่งที่จำเป็นในการส่งออกของฉัน
Kevin S

11

ฉันพบว่ารหัสต่อไปนี้ทำงานได้อย่างสมบูรณ์แบบสำหรับงาน

fig = plt.figure(figsize=[6,6])
ax = fig.add_subplot(111)
ax.imshow(data)
ax.axes.get_xaxis().set_visible(False)
ax.axes.get_yaxis().set_visible(False)
ax.set_frame_on(False)
plt.savefig('data.png', dpi=400, bbox_inches='tight',pad_inches=0)

2
โดยทั่วไปแล้วคำตอบมีประโยชน์มากขึ้นหากพวกเขามีคำอธิบายว่ารหัสนี้มีจุดประสงค์เพื่ออะไรและเหตุใดจึงแก้ปัญหาได้โดยไม่ต้องแนะนำผู้อื่น
Tim Diekmann

7

ฉันตามลำดับนี้และมันก็ทำงานได้เหมือนมีเสน่ห์

plt.axis("off")
fig=plt.imshow(image array,interpolation='nearest')
fig.axes.get_xaxis().set_visible(False)
fig.axes.get_yaxis().set_visible(False)
plt.savefig('destination_path.pdf',
    bbox_inches='tight', pad_inches=0, format='pdf', dpi=1200)

1
ที่จริงแล้วฉันพบว่าคำตอบนี้ง่ายและสะดวกกว่าในการใช้
sikisis

1
อันนี้ใช้ได้สำหรับฉัน; คำตอบที่ยอมรับไม่ได้
Joe

3

สำหรับทุกคนที่ต้องการทำงานเป็นพิกเซลแทนที่จะใช้นิ้ว

รวมทั้งปกติคุณจะต้อง

from matplotlib.transforms import Bbox

จากนั้นคุณสามารถใช้สิ่งต่อไปนี้:

my_dpi = 100 # Good default - doesn't really matter

# Size of output in pixels
h = 224
w = 224

fig, ax = plt.subplots(1, figsize=(w/my_dpi, h/my_dpi), dpi=my_dpi)

ax.set_position([0, 0, 1, 1]) # Critical!

# Do some stuff
ax.imshow(img)
ax.imshow(heatmap) # 4-channel RGBA
ax.plot([50, 100, 150], [50, 100, 150], color="red")

ax.axis("off")

fig.savefig("saved_img.png",
            bbox_inches=Bbox([[0, 0], [w/my_dpi, h/my_dpi]]),
            dpi=my_dpi)

ป้อนคำอธิบายรูปภาพที่นี่


คุณไม่จำเป็นต้องระบุ dpi คุณสามารถใช้ค่าเริ่มต้นfig.dpiแทนได้
intsco

1

วิธีที่ง่ายกว่ามากที่ฉันพบคือการใช้plt.imsave:

    import matplotlib.pyplot as plt
    arr = plt.imread(path)
    plt.imsave('test.png', arr)

คำตอบที่ไม่ถูกต้อง plt.savefig()นี้ช่วยให้ฉันหลังจากค้นหานานสำหรับวิธีการที่จะรักษาความละเอียดและลบช่องว่างด้วย
nihal111

ใช้ได้เฉพาะในกรณีที่คุณต้องการบันทึกอาร์เรย์ (!) เป็นรูปภาพ สิ่งนี้ไม่อนุญาตให้บันทึกตัวเลขโดยพลการ
MaxPowers

คุณหมายถึงอะไรโดยภาพโดยพลการ รูปภาพไม่ใช่อาร์เรย์ของค่าใช่หรือไม่
Parth92

0

คุณอาจลองสิ่งนี้ มันแก้ไขปัญหาของฉัน

import matplotlib.image as mpimg
img = mpimg.imread("src.png")
mpimg.imsave("out.png", img, cmap=cmap)

-1

หากคุณต้องการที่จะแสดงสิ่งที่จะถูกบันทึกฉันขอแนะนำให้ใช้การplt.tight_layoutแปลงซึ่งจริง ๆ แล้วเป็นที่นิยมมากขึ้นเพราะมันไม่ได้ทำการปลูกพืชที่ไม่จำเป็นเมื่อใช้plt.savefig

import matplotlib as plt    
plt.plot([1,2,3], [1,2,3])
plt.tight_layout(pad=0)
plt.savefig('plot.png')

-4

มันใช้งานได้สำหรับฉันบันทึกอาร์เรย์ numpy ที่พล็อตด้วย imshow ไปยังไฟล์

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(10,10))
plt.imshow(img) # your image here
plt.axis("off")
plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, 
        hspace = 0, wspace = 0)
plt.savefig("example2.png", box_inches='tight', dpi=100)
plt.show()
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.