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 out plt.show()
and run plt.savefig()
instead, I get a blank white picture. This question, suggests this is cause by calling show()
before savefig()
, but I have it entirely commented out. Another question has a comment suggesting I can save the ax
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 (where dtf
is the pd.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')
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.
Additional add-up on @ImportanceOfBeingErnest's answer, when bbox_inches='tight'
, 'pad_inches=0.1'
may need to set to larger values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With