【问题标题】:Matplotlib - unable to save image in same resolution as original imageMatplotlib - 无法以与原始图像相同的分辨率保存图像
【发布时间】:2016-01-13 14:03:54
【问题描述】:

我无法以初始分辨率 (1037x627) 保存没有白色边框的图像

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import pyplot, lines
import matplotlib.image as mpimg
from matplotlib.patches import Ellipse
x=[0,0,0,0,0]
y=[0,0,0,0,0]
a=10**1.3*15
inc=25
b=np.cos(np.radians(inc))*a
x[0],y[0]=516.667,313.021
x[1],y[1]=x[0]-a,y[0]
x[2],y[2]=x[0]+a,y[0]
x[3],y[3]=x[0],y[0]+b
x[4],y[4]=x[0],y[0]-b
for pa in range(0,10,5):
    fig, ax = plt.subplots()
    img=mpimg.imread('IC342.png')
    imgplot = plt.imshow(img)
    x[1],y[1]=x[0]-a/2*np.cos(np.radians(pa)),y[0]-a/2*np.sin(np.radians(pa))
    x[2],y[2]=x[0]+a/2*np.cos(np.radians(pa)),y[0]+a/2*np.sin(np.radians(pa))
    x[3],y[3]=x[0]+b/2*np.cos(np.radians(pa+90)),y[0]+b/2*np.sin(np.radians(pa+90))
    x[4],y[4]=x[0]-b/2*np.cos(np.radians(pa+90)),y[0]-b/2*np.sin(np.radians(pa+90))
    ell = Ellipse(xy=[516.667,313.021], width=a, height=b, angle=pa, edgecolor='b',lw=4, alpha=0.5, facecolor='none')
    name='plt'+str(pa)+'.png'
    leg='PA='+str(pa)
    #ax.text(10, 10, leg, fontsize=15,color='white')
    ax.add_artist(ell)
    xn=[x[1],x[2],x[0]]
    yn=[y[1],y[2],y[0]]
    xnw=[x[3],x[4],x[0]]
    ynw=[y[3],y[4],y[0]]
    line = lines.Line2D(xn, yn, linestyle='-.',lw=5., color='r', alpha=0.4)
    line1 = lines.Line2D(xnw, ynw, linestyle='-.',lw=5., color='g', alpha=0.4)
    ax.add_line(line)
    ax.add_line(line1)
    plt.axis('off')
    fig.savefig(name, transparent=True, bbox_inches='tight', pad_inches=0,dpi=150 )

初始图像

结果

我还需要白色文本PA=something 在图像上而不更改分辨率。据我了解,添加另一个图形(如文本)可能会自动更改分辨率。

感谢您的宝贵时间!

【问题讨论】:

    标签: python matplotlib resolution


    【解决方案1】:

    这里有两个因素在起作用:

    1. Axes 默认不会占用整个Figure
    2. matplotlib 中,Figure 的大小是固定的,内容会被拉伸/压缩/插值以适合图形。您希望 Figure 的大小由其内容定义。

    做你想做的事,分为三个步骤:

    1. 根据图像大小和设置的 DPI 创建图形
    2. 添加占据整个图形的子图/轴
    3. 使用用于计算图窗大小的 DPI 保存图窗

    让我们使用来自美国宇航局http://www.nasa.gov/sites/default/files/thumbnails/image/hubble_friday_12102015.jpg 的随机哈勃图像。这是一张 1280x1216 像素的图片。

    这里有一个评论很多的例子来引导你完成它:

    import matplotlib.pyplot as plt
    
    # On-screen, things will be displayed at 80dpi regardless of what we set here
    # This is effectively the dpi for the saved figure. We need to specify it,
    # otherwise `savefig` will pick a default dpi based on your local configuration
    dpi = 80
    
    im_data = plt.imread('hubble_friday_12102015.jpg')
    height, width, nbands = im_data.shape
    
    # What size does the figure need to be in inches to fit the image?
    figsize = width / float(dpi), height / float(dpi)
    
    # Create a figure of the right size with one axes that takes up the full figure
    fig = plt.figure(figsize=figsize)
    ax = fig.add_axes([0, 0, 1, 1])
    
    # Hide spines, ticks, etc.
    ax.axis('off')
    
    # Display the image.
    ax.imshow(im_data, interpolation='nearest')
    
    # Add something...
    ax.annotate('Look at This!', xy=(590, 650), xytext=(500, 500),
                color='cyan', size=24, ha='right',
                arrowprops=dict(arrowstyle='fancy', fc='cyan', ec='none'))
    
    # Ensure we're displaying with square pixels and the right extent.
    # This is optional if you haven't called `plot` or anything else that might
    # change the limits/aspect.  We don't need this step in this case.
    ax.set(xlim=[-0.5, width - 0.5], ylim=[height - 0.5, -0.5], aspect=1)
    
    fig.savefig('test.jpg', dpi=dpi, transparent=True)
    plt.show()
    

    保存的test.jpg 将是 1280x1216 像素。当然,因为我们对输入和输出都使用了有损压缩格式,所以由于压缩伪影,您将无法获得完美的像素匹配。但是,如果您使用无损输入和输出格式,则应该这样做。

    【讨论】:

    • 天哪,非常感谢!!!解释正是我需要的,仅仅解决问题是不够的,我真的很想知道将来要避免什么。我从来没有使用过注释,只是纯文本,这非常有用,我不能再感激了!
    • @Tigs - 乐于助人!
    • 这里stackoverflow.com/a/53816322/5057078说它从80dpi变成了100dpi,所以用dpi = matplotlib.rcParams['figure.dpi']而不是固定数字。
    猜你喜欢
    • 2021-09-19
    • 1970-01-01
    • 2015-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-11
    • 2020-05-25
    • 1970-01-01
    相关资源
    最近更新 更多