Save plot to image file instead of displaying it
This displays the figure in a GUI:
import matplotlib.pyplot as plt
plt.plot([1, 2, 3], [1, 4, 9])
plt.show()
But how do I instead save the figure to a file (e.g. foo.png)?
To save a matplotlib plot to an image file instead of displaying it, use the plt.savefig() or fig.savefig() method after creating your plot. This approach allows you to export your visualization to various file formats like PNG, JPG, PDF, or SVG with customizable quality and formatting options.
Contents
- Basic Savefig Method
- File Format Options
- Key Parameters Explained
- Best Practices and Common Issues
- Complete Examples
- Advanced Techniques
Basic Savefig Method
The fundamental way to save a plot to a file is by using plt.savefig() after creating your plot. Here’s the basic approach:
import matplotlib.pyplot as plt
plt.plot([1, 2, 3], [1, 4, 9])
plt.savefig('foo.png') # Saves the plot to a PNG file
Alternatively, you can work with figure objects directly:
import matplotlib.pyplot as plt
fig, ax = plt.subplots() # Create figure and axes
ax.plot([1, 2, 3], [1, 4, 9])
fig.savefig('foo.png') # Save the specific figure
As noted in the Stack Overflow discussion, this is the standard approach used by most matplotlib users.
File Format Options
Matplotlib supports multiple output formats that are automatically detected based on the file extension. According to the official documentation, the available formats depend on the backend being used:
# Common image formats
plt.savefig('plot.png') # PNG format
plt.savefig('plot.jpg') # JPEG format
plt.savefig('plot.svg') # SVG vector format
plt.savefig('plot.pdf') # PDF vector format
plt.savefig('plot.eps') # EPS vector format
plt.savefig('plot.tiff') # TIFF format
plt.savefig('plot.bmp') # BMP format
The GeeksforGeeks tutorial demonstrates saving plots in various formats, showing how matplotlib automatically determines the format from the file extension.
Key Parameters Explained
DPI (Dots Per Inch)
Controls the resolution and quality of the saved image:
plt.savefig('high_quality.png', dpi=300) # High resolution
plt.savefig('low_quality.png', dpi=72) # Low resolution
According to the Medium article, DPI significantly impacts the quality - higher DPI means larger file size but better quality.
Bounding Box and Padding
Prevents axis labels and titles from being cut off:
plt.savefig('plot.png', bbox_inches='tight', pad_inches=0.1)
The official documentation shows that bbox_inches='tight' ensures all plot elements are included, while pad_inches controls the padding around the content.
Transparency and Background
Control the background appearance:
plt.savefig('transparent.png', transparent=True) # Transparent background
plt.savefig('colored_bg.png', facecolor='yellow') # Custom background color
As explained in the Python Pool guide, the transparent parameter makes the background transparent, which is useful for overlays.
Format-Specific Parameters
Some formats support additional parameters:
# For JPEG files, you can control quality
plt.savefig('photo.jpg', quality=95) # Quality from 0-100
# For vector formats, you can control metadata
plt.savefig('report.pdf', metadata={'Title': 'My Analysis'})
Best Practices and Common Issues
Closing Figures to Prevent Memory Issues
When working in loops or scripts, it’s important to close figures to prevent memory leaks:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [1, 4, 9])
fig.savefig('plot.png')
plt.close(fig) # Close the figure to free memory
As mentioned in the Stack Overflow solution, this prevents having multiple open figures during large loops.
Handling Interactive Mode
In some environments like Spyder with interactive mode enabled, figures might always display. The workaround is to close them explicitly:
import matplotlib.pyplot as plt
# Set up for interactive mode if needed
plt.ion() # Interactive mode on
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [1, 4, 9])
fig.savefig('plot.png')
plt.close(fig) # Force close to prevent display
Avoiding Empty Files
A common issue occurs when trying to save a figure after calling plt.show():
import matplotlib.pyplot as plt
plt.plot([1, 2, 3], [1, 4, 9])
plt.savefig('before_show.png') # This works
plt.show() # This clears the figure
plt.savefig('after_show.png') # This creates an empty file!
As discussed in this Stack Overflow thread, you should save before showing if you want both.
Complete Examples
Basic Line Plot
import matplotlib.pyplot as plt
import numpy as np
# Create sample data
x = np.linspace(0, 10, 100)
y = np.sin(x)
# Create and save plot
plt.figure(figsize=(10, 6))
plt.plot(x, y, 'b-', linewidth=2, label='sin(x)')
plt.xlabel('X values')
plt.ylabel('Y values')
plt.title('Sine Wave')
plt.legend()
plt.grid(True, alpha=0.3)
# Save with high quality
plt.savefig('sine_wave.png', dpi=300, bbox_inches='tight', facecolor='white')
plt.close()
Multiple Subplots
import matplotlib.pyplot as plt
import numpy as np
# Create figure with subplots
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(12, 10))
# Plot different functions
x = np.linspace(0, 10, 100)
ax1.plot(x, np.sin(x), 'r-')
ax1.set_title('Sine')
ax1.grid(True)
ax2.plot(x, np.cos(x), 'g-')
ax2.set_title('Cosine')
ax2.grid(True)
ax3.plot(x, np.exp(-x/5), 'b-')
ax3.set_title('Exponential Decay')
ax3.grid(True)
ax4.plot(x, np.log(x + 1), 'm-')
ax4.set_title('Logarithmic')
ax4.grid(True)
plt.tight_layout()
plt.savefig('multi_plots.png', dpi=150, bbox_inches='tight')
plt.close()
Bar Chart with Custom Styling
import matplotlib.pyplot as plt
# Sample data
categories = ['A', 'B', 'C', 'D', 'E']
values = [23, 45, 56, 78, 32]
# Create bar chart
plt.figure(figsize=(8, 6))
bars = plt.bar(categories, values, color='skyblue', alpha=0.7, edgecolor='navy', linewidth=2)
# Add value labels on bars
for bar in bars:
height = bar.get_height()
plt.text(bar.get_x() + bar.get_width()/2., height,
f'{height}', ha='center', va='bottom', fontsize=12, fontweight='bold')
plt.xlabel('Categories')
plt.ylabel('Values')
plt.title('Sample Bar Chart')
plt.grid(axis='y', alpha=0.3)
# Save as both PNG and PDF
plt.savefig('bar_chart.png', dpi=300, bbox_inches='tight', facecolor='white')
plt.savefig('bar_chart.pdf', bbox_inches='tight', facecolor='white')
plt.close()
Advanced Techniques
Saving with Different Backgrounds
import matplotlib.pyplot as plt
import numpy as np
# Create plot
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(x, y, 'r-', linewidth=3)
ax.set_title('Sine Wave with Different Backgrounds')
# Save with white background
fig.savefig('white_bg.png', facecolor='white', bbox_inches='tight')
# Save with transparent background
fig.savefig('transparent_bg.png', transparent=True, bbox_inches='tight')
# Save with custom colored background
fig.savefig('colored_bg.png', facecolor='lightblue', bbox_inches='tight')
plt.close()
Batch Processing Multiple Plots
import matplotlib.pyplot as plt
import numpy as np
import os
# Create output directory if it doesn't exist
output_dir = 'plots'
os.makedirs(output_dir, exist_ok=True)
# Generate multiple plots for different functions
functions = [
('sin(x)', np.sin, 'red'),
('cos(x)', np.cos, 'blue'),
('tan(x)', np.tan, 'green'),
('exp(-x)', lambda x: np.exp(-x), 'purple')
]
x = np.linspace(0, 10, 100)
for name, func, color in functions:
plt.figure(figsize=(8, 6))
plt.plot(x, func(x), color=color, linewidth=2, label=name)
plt.xlabel('X')
plt.ylabel('Y')
plt.title(f'Plot of {name}')
plt.legend()
plt.grid(True, alpha=0.3)
# Save with high quality
filename = os.path.join(output_dir, f'{name.replace("(", "").replace(")", "")}.png')
plt.savefig(filename, dpi=300, bbox_inches='tight', facecolor='white')
plt.close()
print(f"Saved {len(functions)} plots to {output_dir}/")
Saving with Custom Metadata
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 6))
plt.plot([1, 2, 3, 4], [1, 4, 9, 16], 'bo-')
plt.title('Custom Metadata Example')
plt.xlabel('X values')
plt.ylabel('Y values')
# Save with metadata
metadata = {
'Title': 'My Plot',
'Author': 'Data Scientist',
'Description': 'Example plot with custom metadata',
'Copyright': '2024 My Company'
}
plt.savefig('with_metadata.png', dpi=300, metadata=metadata, bbox_inches='tight')
plt.close()
These examples demonstrate various ways to save matplotlib plots to files while controlling quality, format, and appearance. The key is to use plt.savefig() with appropriate parameters for your specific needs, and always remember to close figures when working in scripts to prevent memory issues.
Sources
- Stack Overflow - Save plot to image file instead of displaying it
- Atlassian - How to Save a Plot to a File Using Matplotlib
- Sentry - Save a Matplotlib plot to a file in Python
- GeeksforGeeks - How to Save a Plot to a File Using Matplotlib
- Matplotlib Documentation - matplotlib.pyplot.savefig
- Python Pool - Matplotlib Savefig() For Different Parameters
- Medium - Using matplotlib savefig Effectively
- Problem Solving 101 with Python - Saving plots
Conclusion
Saving matplotlib plots to files instead of displaying them is straightforward using the plt.savefig() method. The key takeaways are:
- Use
plt.savefig('filename.png')orfig.savefig('filename.png')to save your plot - Control quality with the
dpiparameter (300 for high quality, 72 for web) - Use
bbox_inches='tight'to prevent labels from being cut off - Set
transparent=Truefor transparent backgrounds orfacecolorfor custom backgrounds - Support multiple formats (PNG, JPG, PDF, SVG, etc.) based on file extension
- Always close figures with
plt.close(fig)in scripts to prevent memory leaks - Save before calling
plt.show()to avoid empty files
By mastering these techniques, you can efficiently generate and save professional-quality visualizations for reports, presentations, and web applications.