Keywords: Matplotlib | DPI | Figure Size
Abstract: This article delves into the core relationship between DPI (Dots Per Inch) and figure size (figsize) in Matplotlib, explaining why adjusting only figure size leads to disproportionate visual elements. By analyzing pixel calculation, point unit conversion, and visual scaling mechanisms, it provides systematic solutions to figure scaling issues and demonstrates how to balance DPI and figure size for optimal output. The article includes detailed code examples and visual comparisons to help readers master key principles of Matplotlib rendering.
Introduction
When using Matplotlib for data visualization, many developers encounter issues where output figure dimensions do not match expectations, particularly when adjusting figure size causes disproportionate scaling of axes, lines, and annotations. This often stems from misunderstandings about the relationship between DPI (Dots Per Inch) and figure size (figsize). Based on high-quality discussions from Stack Overflow, this article systematically analyzes the interaction between these two parameters and provides practical solutions.
Basic Definitions of DPI and Figure Size
In Matplotlib, figure size (figsize) is specified in inches, defining the physical dimensions of the canvas. For example, the default figure size is (6.4, 4.8) inches, providing layout space for axes and other elements. Increasing figure size is akin to using larger paper but does not alter the intrinsic size of drawn elements.
DPI (Dots Per Inch) determines the pixel density of digital output. The calculation formula is: pixels = figure size (inches) × DPI. For instance, a 6.4×4.8-inch figure at 100 DPI produces a 640×480-pixel image. By varying combinations of DPI and figure size, identical pixel outputs can be achieved, but visual effects differ significantly.
Scaling Mechanisms of Visual Elements
Elements such as lines, markers, and text in Matplotlib are typically sized in points. By default, Matplotlib uses 72 PPI (Points Per Inch) for conversion, meaning 1 point equals 1/72 inch. This mechanism is key to understanding scaling issues:
- Adjusting Figure Size: When only figure size is changed (e.g., from
(6,4)to(12,8)inches), point-sized elements remain constant, so they appear relatively smaller on the larger canvas, creating a "zoomed-out" effect. This is similar to drawing with a thick pen on small paper and then transferring to larger paper—the line does not thicken, but visual proportions change. - Adjusting DPI: Changing DPI directly affects point-to-pixel conversion. For example, at 72 DPI, a 1-point line corresponds to 1 pixel; at 144 DPI, the same line corresponds to 2 pixels, producing a "magnifying glass" effect where all elements scale proportionally.
The following code example demonstrates visual effects under different DPI and figure size combinations:
import matplotlib.pyplot as plt
def plot_example(figsize, dpi):
fig, ax = plt.subplots(figsize=figsize, dpi=dpi)
ax.set_title(f"Figsize: {figsize}, DPI: {dpi}")
ax.plot([1, 2, 3, 4], [2, 4, 1, 5], label="Example Line", linewidth=2)
ax.legend()
plt.savefig(f"output_{figsize[0]}_{dpi}.png")
plt.close()
# Compare different DPIs with same figure size
plot_example((4, 3), 72)
plot_example((4, 3), 144)
# Compare different figure sizes with same DPI
plot_example((2, 1.5), 100)
plot_example((8, 6), 100)
Practical Solutions to Figure Scaling Issues
For the user's issue of "abnormal scaling of figure elements," the root cause lies in adjusting only figure size without considering DPI. For example, to achieve a target output of 1200×600 pixels, multiple combinations are possible:
figsize=(15,7.5), dpi=80figsize=(12,6), dpi=100figsize=(8,4), dpi=150figsize=(6,3), dpi=200
The choice depends on specific needs:
- Maintaining Visual Proportions: To keep elements like lines and text consistent with screen previews, prioritize adjusting figure size and match DPI to the display device (typically 72-96 DPI).
- High-Resolution Output: For print or high-definition exports, increase DPI (e.g., 300-400) while proportionally reducing figure size to avoid oversized files.
- Dynamic Adjustment: When using
fig.set_size_inches()andplt.savefig(dpi=...), ensure coordination. For instance, if saving with high DPI, reduce figure size accordingly to maintain total pixels.
Below is a corrected code example ensuring output image dimensions of 1200×600 pixels with harmonious visual proportions:
import matplotlib.pyplot as plt
# Set figure size and DPI to match target pixels
fig, ax = plt.subplots(figsize=(6, 3)) # 6 inches × 3 inches
fig.set_size_inches(6, 3) # Explicitly set size
# Plot elements
ax.plot([0, 1, 2, 3], [0, 1, 4, 9], color="blue", linewidth=1.5)
ax.set_xlabel("X-axis", fontsize=10)
ax.set_ylabel("Y-axis", fontsize=10)
# Save with specified DPI to achieve target pixels: 6*200=1200, 3*200=600
plt.savefig("output_fixed.jpg", dpi=200, edgecolor="black", facecolor="white", transparent=False)
plt.close()
Advanced Considerations and Best Practices
In practical applications, additional factors should be considered:
- Cross-Platform Consistency: DPI variations across operating systems and displays may cause discrepancies between preview and output. Test results on target devices.
- Vector Graphic Output: For PDF or SVG formats, DPI settings do not affect vector elements, but figure size still determines layout proportions.
- Performance Trade-offs: High-DPI images increase file size and processing time; balance quality and efficiency based on use case.
By understanding the deep relationship between DPI and figure size, developers can precisely control Matplotlib output, avoid common scaling pitfalls, and enhance the professionalism of visualizations.