Change figure size and figure format in matplotlib [duplicate] - python

This question already has answers here:
How do I change the size of figures drawn with Matplotlib?
(14 answers)
Closed 1 year ago.
I want to obtain fig1 exactly of 4 by 3 inch sized, and in tiff format correcting the program below:
import matplotlib.pyplot as plt
list1 = [3,4,5,6,9,12]
list2 = [8,12,14,15,17,20]
plt.plot(list1, list2)
plt.savefig('fig1.png', dpi = 300)
plt.close()

You can set the figure size if you explicitly create the figure with
plt.figure(figsize=(3,4))
You need to set figure size before calling plt.plot()
To change the format of the saved figure just change the extension in the file name. However, I don't know if any of matplotlib backends support tiff

You can change the size of the plot by adding this before you create the figure.
plt.rcParams["figure.figsize"] = [16,9]

The first part (setting the output size explictly) isn't too hard:
import matplotlib.pyplot as plt
list1 = [3,4,5,6,9,12]
list2 = [8,12,14,15,17,20]
fig = plt.figure(figsize=(4,3))
ax = fig.add_subplot(111)
ax.plot(list1, list2)
fig.savefig('fig1.png', dpi = 300)
fig.close()
But after a quick google search on matplotlib + tiff, I'm not convinced that matplotlib can make tiff plots. There is some mention of the GDK backend being able to do it.
One option would be to convert the output with a tool like imagemagick's convert.
(Another option is to wait around here until a real matplotlib expert shows up and proves me wrong ;-)

If you need to change the figure size after you have created it, use the methods
fig = plt.figure()
fig.set_figheight(value_height)
fig.set_figwidth(value_width)
where value_height and value_width are in inches. For me this is the most practical way.

Related

Save matplotlib to final given size including titles [duplicate]

This question already has answers here:
How to adjust padding with cutoff or overlapping labels
(8 answers)
Closed 4 years ago.
I am making figures for publication. I need the final figure, including the titles and text to be 3 inches wide and saved as a .tiff file. I know I can specify the size of the plot via matplotlib using
matplotlib.pyplot.figure(figsize=(3,2), dpi=300)
However this only specifies the size of the actual plot, not including the titles and everything. Also, the titles get cut off of my saved .tiff file when I try this method. Of course the easy fix is to decrease the size of the plot and manually make the figure the correct size, but does anyone know of an automatic way to make the plot be a given final size with all the bells and whistles included?
Here is the output image which is saved (this one is a png so it can upload to stackoverflow). Note the plot titles are cut off for some reason.
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from PIL import Image
from io import BytesIO
bent=[2.83263904,2.75860489,2.64546045,2.4949913,2.34923737,2.16430217,2.02562783,1.82478841,1.70324689,1.70315642,1.39739535,1.33945747,1.22295623,1.15726486,1.08449954,0.96155077,0.90325786,0.84547091]
bent=[i/27 for i in bent]
print(bent)
planar=[4.11233905,3.93027011,3.65135645,3.38525615,3.1130921,2.81042899,2.58995789,2.36159934,2.15981447,1.9964454,1.74375941,1.63263452,1.48503205,1.38596544,1.26501988,1.17391638,1.07490417,0.99369748]
planar=[i/27 for i in planar]
bi=[2.51027966,2.56495852,2.47033072,2.33008642,2.19395126,2.13732249,1.80922673,1.76037446,1.52930137,1.56732451,1.33905847,1.24952153,1.15699233,1.08251496,0.98449116,0.93838164,0.86542147,0.725736]
bi=[i/34 for i in bi]
T=[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
arr=[bi,bent,planar]
arr=np.array(arr)
arr=arr.T
font = {'family' : 'normal',
'weight' : 'normal',
'size' : 8}
matplotlib.rc('font', **font)
fig = plt.figure(figsize=(3,2), dpi=300)
plt.title("-ΔS$_m$ vs T") #for Fe$_4$Gd
plt.xlabel('Temperature (K)')
plt.ylabel("$-ΔS_m$ ($J.K^{-1}.mol^{-1}n (e^{-})^{-1}$)")
MMM=('Fe$_4$Gd$_2$','Fe$_4$Gd bent','Fe$_4$Gd planar')
plt.plot(T,arr,'o')
plt.legend(MMM, loc='best')
# save figure
# (1) save the image in memory in PNG format
png1 = BytesIO()
fig.savefig(png1, format='png')
# (2) load this image into PIL
png2 = Image.open(png1)
# (3) save as TIFF
png2.save('TESTTESTTEST.tiff')
png1.close()
Use plt.tight_layout(). You can find more details here.

plt.savefig output image quality

I am trying to save a plot into a file using plt.savefig, however I am dissatisfied with the output picture quality. Changing dpi option doesn't help.
plt.savefig('filename.png', dpi=1200, format='png', bbox_inches='tight')
I tried saving to 'svg' and 'eps' - makes no difference. I wonder if the problem is with something else, like version of some library or OS or something alike. It also looks like the problem is not with resolution but the way lines and symbols are drawn - too bold.
plt.show() shows significantly better picture, and I can save it to png with satisfying quality - and surprisingly file size is about 8 times smaller (because of compressing, I suppose, which is fine.)
Part of the picture saved using savefig()
The same part of the picture saved from plot.show()
Figsize option did the trick for me.
The idea is that default parameters for saving to file and for displaying the chart are different for different devices. That's why representation was different in my case.
It's possible to adjust settings manually (as Piotrek suggests), but for me it was enough just to increase figure size - this setting is shared and allows python to auto-adjust visualization.
More details are on the page Piotrek mentioned, answered by doug and Karmel.
I have several subplots, so i used it like that:
fig, ax = plt.subplots(nrows=4, ncols=1, figsize=(20, 10))
For one plot case command is like that:
plt.figure(figsize=(20,10))
P.S. figsize parameters are in inches, not pixels.
Have a look here: Styles and Futurile
In short, you can experiment with the following options to edit the line, ticks etc.
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.serif'] = 'Ubuntu'
plt.rcParams['font.monospace'] = 'Ubuntu Mono'
plt.rcParams['font.size'] = 10
plt.rcParams['axes.labelsize'] = 10
plt.rcParams['axes.labelweight'] = 'bold'
plt.rcParams['axes.titlesize'] = 10
plt.rcParams['xtick.labelsize'] = 8
plt.rcParams['ytick.labelsize'] = 8
plt.rcParams['legend.fontsize'] = 10
plt.rcParams['figure.titlesize'] = 12
Also have a look at this topic:
matplotlib savefig() plots different from show()

Matplotlib figsize not respected [duplicate]

This question already has answers here:
Matplotlib and Ipython-notebook: Displaying exactly the figure that will be saved
(2 answers)
Closed 4 years ago.
I want to make a square plot with matplotlib. That is, I want the whole figure to be square. When I use the following code, the width of the resulting image is still a bit larger than the height. Why is matplotlib not respecting the figsize I provide?
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 10))
# When inspecting in browser, reveals 611x580 px image
ax.plot([1,2,3], [1,2,3])
Edit: I display the image inline in a Jupyter notebook, and just use the Chrome developer tools to inspect the image.
That is a problem of jupyter notebook. The figure it shows is a "saved" version, which uses the bbox_inches="tight" option and hence changes the size of the shown image.
One option you have is to save the figure manually to png,
fig.savefig("output.png")
As #EvgenyPogrebnyak commented, the other option is to deactivate the "tight" option in the notebook as
%matplotlib inline
%config InlineBackend.print_figure_kwargs = {'bbox_inches':None}
fig, ax = plt.subplots(figsize=(10, 10))
# When inspecting in browser,
ax.plot([1,2,3], [1,2,3]) # now reveals 720 x 720 px image
as seen in this answer.

How to embed a zoomed portion of a FITS image in the same plot with APLpy

I want to embed a zoomed portion of a FITS image in the same plot with APLpy.
But when loading a FITS file with APLpy, there is only a 'FITSFigure' object returned.
fig = aplpy.FITSFigure('tmp.fits', slices=[0,0])
Is it possible to make it work with zoomed_inset_axes like here , or there are some other solution?
You may specify the figure to which to plot with aplpy. You can then get the axes inside the figure.
fig = plt.figure()
aplpyfig = aplpy.FITSFigure('tmp.fits', figure=fig)
axes = fig.get_axes()
From that point onwards you can work with that axes and use any of the methods that matplotlib offers to obtain insets.
Also see this question: Aplpy multiplot dynamic axis sharing

(Matplotlib, python) long subplots, scrolling

I would like to create a pdf file [by using plt.savefig("~~~.pdf")]
containing lots of (about 20) subplots
each of which is drawing timeseries data.
I am using a matplotlib library with python language.
Each subplot may be long, and I want to put the subplots
horizontally.
Therefore, the figure should be very long (horizontally), so the horizontal scroll bar should be needed!
Is there any way to do this?
some example code will be appreciated!
The following is my sample code.
I just wanted to draw 10 sine graphs arranged horizontally
and save it as pdf file.
(but I'm not pretty good at this. so the code may looks to be weird to you.. :( )
from matplotlib import pyplot as plt
import numpy as np
x=np.linspace(0,100,1000)
y=np.sin(x)
numplots=10
nr=1
nc=numplots
size_x=nc*50
size_y=size_x*3/4
fig=plt.figure(1,figsize=(size_x,size_y))
for i in range(nc):
ctr=i+1
ax=fig.add_subplot(nr,nc,ctr)
ax.plot(x,y)
plt.savefig("longplot.pdf")
plt.clf()
Thank you!
You should do that using the backend "matplotlib.backends.backend_pdf". This enables you to save matplotlib graphs in pdf format.
I have simplified your code a bit, here is a working example:
from matplotlib import pyplot as plt
import numpy as np
from matplotlib.backends.backend_pdf import PdfPages
x = np.linspace(0,100,1000)
y = np.sin(x)
nr = 10
nc = 1
for i in range(nr):
plt.subplot(nr, nc, i + 1)
plt.plot(x, y)
pdf = PdfPages('longplot.pdf')
pdf.savefig()
pdf.close()
I hope this helps.
In the link below there is a solution, which can help you, since it was helpful to me either.
Scrollbar on Matplotlib showing page
But if you have many subplots, I am afraid your problem won't be solved. Since it will shrink each graph anyway. In that case it will be better to break your graphs into smaller and separate parts.

Categories

Resources