Get exact image dimensions with matplotlib and bbox_inches='tight' - python

I plot a series of figures and save them via savefig as png files (where savefig gets dpi=100 as an argument). The aspect ratio and resolution is previously defined within plt.figure(figsize=(10.24, 10.24), dpi=100), which should result in images of exactly 1024x1024 pixels. I use bbox_inches='tight' as well as plt.tight_layout(), but I still get image dimensions that vary about a few pixels from one image to the next, depending on the axis labels it seems.
Did I miss something? How do I get the exact same image dimensions for every file without losing bbox_inches='tight'? Using matplotlib 1.3.1.

Related

Python matplotlib reducing the image resolution [duplicate]

In matplotlib, I am using LineCollection to draw and color the countries, where the boundaries of the counties are given. When I am saving the figure as a pdf file:
fig.savefig('filename.pdf',dpi=300)
the figure size are quite big. However, on saving them as png file:
fig.savefig('filename.png',dpi=300)
and then converting them to pdf using linux convert command the files are small. I tried reducing the dpi, however that do not change the pdf file size. Is there a way the figures can be saved directly as smaller-pdf files from matplotlib?
The PDF is larger, since it contains all the vector information. By saving a PNG, you produce a rasterized image. It seems that in your case, you can produce a smaller PDF by rasterizing the plot directly:
plt.plot(x, y, 'r-', rasterized=True)
Here, x, y are some plot coordinates. You basically have to use the additionally keyword argument raterized to achieve the effect.
I think using "rasterized = True" effectively saves the image similarly to png format. When you zoom in, you will see blurring pixels.
If you want the figures to be high quality, my suggestion is to sample from the data and make a plot. The pdf file size is roughly the amount of data points it need to remember.

How to save an image plotted with matplolib 1.5

I want to save an image plotted with matplotlib. For that, I use the function savefig which has different parameters.
The problem is that when I saved the image, this function add additional white pixel.
In short, I would like to save the image I draw with the original size. In other words, if the data I draw has a dimension of 1000x560, I save the image with those dimensions without additional white parts.
Thus in this way a pixel of the saved image coincides with the pixel that the figure of matplotlib can see.
I'm using python 2.7
Can anyone help please?
Thanks
from matplotlib import pyplot as plt
plt.savefig('foo.png', bbox_inches='tight')

How to make a heatmap using Matplotlib with a specific pixel size for each cell?

I can easily make my heatmap using
data = np.random.rand(4,4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)
plt.show()
However as you can see each cell is rectangular and I'd like each one to be square (32 x 32 pixels), generating a 512 x 512 pixel image.
Is there a way of forcing the plot (or each individual cell) to be of a specific pixel size?
Edits:
my screen DPI is 100
I'd like the actual heatmap to be 512 x 512 and
not the entire figure
If you only want an image containing colors associated with your values and no tick marks or labels, I would suggest using PIL.Image.fromarray from the Pillow fork of PIL. you'll need to tile your array so each value is repeated 32x32 then create your image probably using float32 mode or int32 mode.. im = PIL.Image.fromarray(ndarray, mode='f')
PIL also allows you to resize an image, so you could create the image with one pixel per bin then resize with no per pixel re-sampling: im.resize((512,512),resample=0)
Here I'm quoting from a previous post attached below:
Matplotlib doesn't work with pixels directly, but rather physical
sizes and DPI. If you want to display a figure with a certain pixel
size, you need to know the DPI of your monitor. For example this link
will detect that for you.
If you have an image of 3841x7195 pixels it is unlikely that you
monitor will be that large, so you won't be able to show a figure of
that size (matplotlib requires the figure to fit in the screen, if you
ask for a size too large it will shrink to the screen size). Let's
imagine you want an 800x800 pixel image just for an example. Here's
how to show an 800x800 pixel image in my monitor (my_dpi=96):
plt.figure(figsize=(800/my_dpi, 800/my_dpi), dpi=my_dpi) So you
basically just divide the dimensions in inches by your DPI.
If you want to save a figure of a specific size, then it is a
different matter. Screen DPIs are not so important anymore (unless you
ask for a figure that won't fit in the screen). Using the same example
of the 800x800 pixel figure, we can save it in different resolutions
using the dpi keyword of savefig. To save it in the same resolution as
the screen just use the same dpi:
plt.savefig('my_fig.png', dpi=my_dpi) To to save it as an 8000x8000
pixel image, use a dpi 10 times larger:
plt.savefig('my_fig.png', dpi=my_dpi * 10) Note that the setting of
the DPI is not supported by all backends. Here, the PNG backend is
used, but the pdf and ps backends will implement the size differently.
Also, changing the DPI and sizes will also affect things like
fontsize. A larger DPI will keep the same relative sizes of fonts and
elements, but if you want smaller fonts for a larger figure you need
to increase the physical size instead of the DPI.
Getting back to your example, if you want to save a image with 3841 x
7195 pixels, you could do the following:
plt.figure(figsize=(3.841, 7.195), dpi=100) ( your code ...)
plt.savefig('myfig.png', dpi=1000) Note that I used the figure dpi of
100 to fit in most screens, but saved with dpi=1000 to achieve the
required resolution. In my system this produces a png with 3840x7190
pixels -- it seems that the DPI saved is always 0.02 pixels/inch
smaller than the selected value, which will have a (small) effect on
large image sizes. Some more discussion of this here.
Specifying and saving a figure with exact size in pixels
Hope it helps!

python imshow pixel size varies within plot

Dear stackoverflow community!
I need to plot a 2D-map in python using imshow. The command used is
plt.imshow(ux_map, interpolation='none', origin='lower', extent=[lonhg_all.min(), lonhg_all.max(), lathg_all.min(), lathg_all.max()])
The image is then saved as follows
plt.savefig('rdv_cr%s_cmlon%s_ux.png' % (2097, cmlon_ref))
and looks like
The problem is that when zooming into the plot one can notice that the pixels have different shapes (e.g. different width). This is illustrated in the zoomed part below (taken from the top region of the the first image):
Is there any reason for this behaviour? I input a rectangular grid for my data, but the problem does not have to do with the data itself, I suppose. Instead it is probably something related to rendering. I'd expect all pixels to be of equal shape, but as could be seen they have both different widths as well as heights. By the way, this also occurs in the interactive plot of matplotlib. However, when zooming in there, they become equally shaped all of a sudden.
I'm not sure as to whether
https://github.com/matplotlib/matplotlib/issues/3057/ and the link therein might be related, but I can try playing around with dpi values. In any case, if anybody knows why this happens, could that person provide some background on why the computer cannot display the plot as intended using the commands from above?
Thanks for your responses!
This is related to the way the image is mapped to the screen. To determine the color of a pixel in the screen, the corresponding color is sampled from the image. If the screen area and the image size do not match, either upsampling (image too small) or downsampling (image too large) occurs.
You observed a case of upsampling. For example, consider drawing a 4x4 image on a region of 6x6 pixels on the screen. Sometimes two screen pixels fall into an image pixel, and sometimes only one. Here, we observe an extreme case of differently sized pixels.
When you zoom in in the interactive view, this effect seems to disapear. That is because suddenly you map the image to a large number of pixels. If one image pixel is enlarged to, say, 10 screen pixels and another to 11, you hardly notice the difference. The effect is most apparent when the image nearly matches the screen resolution.
A solution to work around this effect is to use interpolation, which may lead to an undesirable blurred look. To reduce the blur you can...
play with different interpolation functions. Try for example 'kaiser'
or up-scale the image by a constant factor using nearest neighbor interpolation (e.g. replace each pixel in the image by a block of pixels with the same color). Then any blurring will only affect the edges of the block.

Force pyplot.imshow() to produce image with higher resolution

I have an NxN array that I am plotting in Python using matplotlib.pyplot.imshow(). N will be very large and I want my final image to have resolution to match. However, in the code that follows, the image resolution doesn't seem to change with increasing N at all. I think that imshow() (at least how I'm using it) has a fixed minimum pixel size that is larger than that needed to show my NxN array with full resolution.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
array = np.loadtxt("output.dat",unpack=True)
plt.figsize=(30.0, 30.0)
im = plt.imshow(array,cmap='hot')
plt.colorbar(im)
plt.savefig("mandelbrot.pdf")
As you can see in the code above, I've tried messing with plt.figsize to try and increase resolution but to no avail. I've also tried various output formats (.pdf, .ps, .eps, .png) but these all produced images with lower resolution than I wanted. The .ps, .eps, and .pdf images all looked the exact same.
First, does my problem exist with imshow() or is there some other aspect of my code that needs to be changed to produce higher resolution images?
Second, how do I produce higher resolution images?
plt.figsize() will only change the size of the figure in inches while keeping the default dpi. You can set the resolution of the figure by passing the dpi keyword argument when you save the figure:
fig.savefig('filename.extension', dpi=XXX)
So if you have a figure size of 4x6 and save it with dpi=300 you'll end up with an image with 1200x1800 resolution.
You can also set the default figure size and dpi with matplotlibrc.

Categories

Resources