'matplotlib savefig() size control
I wrote a function that took a dataframe generated from Pandas and produce a heatmap:
def drawHeatMap(df, city, province, collector, classtype, color, titleposy):
try:
thePlot = pl.matshow(df.values, cmap='PuBuGn')
pl.colorbar(thePlot, orientation='vertical')
aTitle = (classtype + ' Composition Changes Over Time in ' + city +
', ' + province + '\n' + collector + ' collector. ' + 'rs100')
pl.title(aTitle, x=0.5, y=titleposy, style='oblique', weight='bold')
pl.xlabel('Collection Time')
pl.xticks(range(len(df.columns)), df.columns, rotation=90)
pl.yticks(range(len(df.index)), df.index)
fileName = (classtype + '-' + city + '-'
+ province + '-' + collector + '.png')
pl.savefig(fileName)
except ZeroDivisionError:
errorMessage = ('No Data Avaiable for ' + city + ', ' + province +
' with ' + collector + ' collector.')
print errorMessage
The problem I am having is, savefig() would save figures with the axis and graphics trimmed. I have to use show(), maximize the graph and manually save the figure with the GUI button myself.
How can I fix my function so savefig() would save the graphs properly? I tried to put a line like this before pl.savefig() to control my figure:
pl.figure(figsize=....)
but I end up producing some empty graphs. What is the proper way to write a matplotlib function that give me full control on saving the figure?
Updated with Example of a problem figure:

Solution 1:[1]
I added plt.tight_layout() before savefig(), and it solved the trimming issue I had. Maybe it will help yours as well.
EDIT: I also set the figure size at the begining rcParams['figure.figsize'] = 40, 12(you can set your own width and height)
Solution 2:[2]
From the documentation, you can add a dpi argument to set the resolution.
savefig('foo.png', dpi=199)
Solution 3:[3]
Short:
You just need to call pl.figure(figsize=...) before you call the pl.colorbar (and all the other stuff)
Explanation:pl.figure creates a new figure (with given size), on which all pl.* methods will act in the following.
So pl.savefig just saves the last created figure, which is empty if you created a new one in the preceeding line.
Solution 4:[4]
before calling pl.savefig(fileName)
do plt.tight_layout()
Solution 5:[5]
The command pl.figure() makes a new matplotlib figure. The figure size is set at instantiation. You do want to set the figure size, but you already have a figure. So you were on the right track, but try this instead:
def drawHeatMap(df, city, province, collector, classtype, color, titleposy):
try:
fig = pl.figure(figsize=(....))
ax = fig.add_subplot(111)
ax.matshow(df.values, cmap='PuBuGn')
pl.colorbar()
aTitle = classtype + ' Composition Changes Over Time in ' + city + ', ' + province + '\n' + collector + ' collector. ' + 'rs100'
ax.set_title(aTitle, x=0.5, y=titleposy, style='oblique', weight='bold')
ax.set_xlabel('Collection Time')
ax.set_xticks(range(len(df.columns)), df.columns, rotation=90)
ax.set_yticks(range(len(df.index)), df.index)
fileName = classtype + '-' + city + '-' + province + '-' + collector + '.png'
fig.savefig(fileName)
except ZeroDivisionError:
errorMessage = 'No Data Available for ' + city + ', ' + province + ' with ' + collector + ' collector.'
print errorMessage
Solution 6:[6]
you can use the dpi parameter to set The resolution in dots per inch in savefig method. so you can control the figure size. for example, if you this code :
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({
'ser1' : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ,
'ser2' : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
})
df.plot()
plt.savefig("100.png" , dpi = 100)
plt.savefig("300.png" , dpi = 300)
100.png will be :
300.png will be :
Solution 7:[7]
To save figure on desired size
figure = plt.gcf()
figure.set_size_inches(width/100, height/100)
plt.axis('off')
plt.plot(x, y, color='black', linewidth=1)
plt.gca().set_position([0, 0, 1, 1])
plt.savefig("image.png", dpi=100)
Solution 8:[8]
You need to use the set_size_inches function and the dpi parameter in savefig together to define the saved figure size in pixels.
- set the figure width and height in inches through
plt.gcf().set_size_inches(10, 5). - define the
dpiwhile saving the figureplt.savefig('filename.png', dpi=100).dpimeans "dot per inch". - The saved figure width will be 1000(10x100) and the height will be 500(5x100). The saved figure size will be 1000x500 in pixels.
Sample code piece:
import matplotlib.pyplot as plt
def fig_size():
plt.plot(range(0, 10), range(0, 10))
plt.gcf().set_size_inches(10, 5)
plt.savefig('charts/fig_size.png', dpi=200)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | hitzg |
| Solution 3 | sodd |
| Solution 4 | Kumail Haider |
| Solution 5 | G-Nugget |
| Solution 6 | |
| Solution 7 | Zorro |
| Solution 8 |
