Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib - unable to save image in same resolution as original image

I am unable to save the image without the white borders and at the initial resolution (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 )

initial image

Initial img

Result

Resulting img

Also I need the white text PA=something to be on the image without changing the resolution. From what I understand adding another figure like text might automatically change the resolution.

Thank you for your time!

like image 449
Tigs Avatar asked Jan 13 '16 14:01

Tigs


People also ask

How do I save Matplotlib figures with high resolution?

To save the file in pdf format, use savefig() method where the image name is myImagePDF. pdf, format="pdf". We can set the dpi value to get a high-quality image. Using the saving() method, we can save the image with format=”png” and dpi=1200.

How do I save a high resolution image from Python?

To get a high-quality image, we can use . eps image format. You can increase the dot per inch value, i.e., dpi. Using savefig() method, we can save the image locally.

What does dpi mean in Matplotlib?

The dpi method of figure module of matplotlib library is the resolution in dots per inch. Syntax: fig.dpi. Parameters: This method does not accept any parameters. Returns: This method returns resolution in dots per inch.


1 Answers

There are two factors at play here:

  1. An Axes doesn't take up the entire Figure by default
  2. In matplotlib, the Figure's size is fixed, and the contents are stretched/squeezed/interpolated to fit the figure. You want the Figure's size to be defined by its contents.

To do what you want to do, there are three steps:

  1. Create a figure based on the size of the image and a set DPI
  2. Add a subplot/axes that takes up the entire figure
  3. Save the figure with the DPI you used to calculate figure's size

Let's use a random Hubble image from Nasa http://www.nasa.gov/sites/default/files/thumbnails/image/hubble_friday_12102015.jpg. It's a 1280x1216 pixel image.

Here's a heavily commented example to walk you through it:

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()

enter image description here

The saved test.jpg will be exactly 1280x1216 pixels. Of course, because we're using a lossy compressed format for both input and output, you won't get a perfect pixel match due to compression artifacts. If you used lossless input and output formats you should, though.

like image 167
Joe Kington Avatar answered Sep 29 '22 11:09

Joe Kington