Saving matplotlib subplot figure to image file
Solution 1
Remove the line plt.figure(figsize=(12, 9))
and it will work as expected. I.e. call savefig
before show
.
The problem is that the figure being saved is the one created by plt.figure()
, while all the data is plotted to ax
which is created before that (and in a different figure, which is not the one being saved).
For saving the figure including the legend use the bbox_inches="tight"
option
plt.savefig('test.png', bbox_inches="tight")
Of course saving the figure object directly is equally possible,
fig.savefig('test.png', bbox_inches="tight")
For a deeper understanding on how to move the legend out of the plot, see this answer.
Solution 2
Additional add-up on @ImportanceOfBeingErnest's answer, when bbox_inches='tight'
, 'pad_inches=0.1'
may need to set to larger values.
Hendy
Updated on June 24, 2022Comments
-
Hendy almost 2 years
I'm fairly new to
matplotlib
and am limping along. That said, I haven't found an obvious answer to this question.I have a scatter plot I wanted colored by groups, and it looked like plotting via a loop was the way to roll.
Here is my reproducible example, based on the first link above:
import matplotlib.pyplot as plt import pandas as pd from pydataset import data df = data('mtcars').iloc[0:10] df['car'] = df.index fig, ax = plt.subplots(1) plt.figure(figsize=(12, 9)) for ind in df.index: ax.scatter(df.loc[ind, 'wt'], df.loc[ind, 'mpg'], label=ind) ax.legend(bbox_to_anchor=(1.05, 1), loc=2) # plt.show() # plt.savefig('file.png')
Uncommenting
plt.show()
yields what I want:Searching around, it looked like
plt.savefig()
is the way to save a file; if I re-comment outplt.show()
and runplt.savefig()
instead, I get a blank white picture. This question, suggests this is cause by callingshow()
beforesavefig()
, but I have it entirely commented out. Another question has a comment suggesting I can save theax
object directly, but that cuts off my legend:The same question has an alternative that uses
fig.savefig()
instead. I get the same chopped legend.There's this question which seems related, but I'm not plotting a
DataFrame
directly so I'm not sure how to apply the answer (wheredtf
is thepd.DataFrame
they're plotting):plot = dtf.plot() fig = plot.get_figure() fig.savefig("output.png")
Thanks for any suggestions.
Edit: to test the suggestion below to try
tight_layout()
, I ran this and still get a blank white image file:fig, ax = plt.subplots(1) plt.figure(figsize=(12, 9)) for ind in df.index: ax.scatter(df.loc[ind, 'wt'], df.loc[ind, 'mpg'], label=ind) ax.legend(bbox_to_anchor=(1.05, 1), loc=2) fig.tight_layout() plt.savefig('test.png')