As you create visualizations, you'll often find that the default size isn't quite right. Maybe the plot feels cramped, or perhaps it's too large for the document or web page where you intend to place it. Similarly, you might want to display multiple related plots together in a single image for comparison. This section covers how to control the overall size of your plotting area and how to arrange multiple plots within it.
In Matplotlib, the entire image containing your plot(s) is called the Figure
. Think of it as the canvas upon which you draw. You can specify the size of this canvas when you create it. The most common way to do this is using the figsize
argument, which expects a tuple of (width, height)
in inches.
You can set the figure size when initially creating the figure using plt.figure()
or, more commonly, when creating a figure and its associated Axes using plt.subplots()
.
import matplotlib.pyplot as plt
import numpy as np
# Sample data
x = np.linspace(0, 10, 100)
y = np.sin(x)
# Create a figure with a specific size (e.g., 8 inches wide, 4 inches tall)
fig1, ax1 = plt.subplots(figsize=(8, 4))
ax1.plot(x, y)
ax1.set_title('Figure Size: 8x4 inches')
ax1.set_xlabel('X-axis')
ax1.set_ylabel('Y-axis')
plt.show()
# Create another figure with a different size (e.g., 6 inches wide, 6 inches tall)
fig2, ax2 = plt.subplots(figsize=(6, 6))
ax2.plot(x, y, color='#fa5252') # Using a red color from the palette
ax2.set_title('Figure Size: 6x6 inches')
ax2.set_xlabel('X-axis')
ax2.set_ylabel('Y-axis')
plt.show()
Changing the figsize
affects the aspect ratio (the ratio of width to height) and the overall space available for plot elements like titles, labels, and the plotting area itself. Experimenting with different figsize
values helps you find the dimensions that best suit your data and presentation needs.
Another related parameter is dpi
(dots per inch), which controls the resolution of the figure, particularly important when saving the plot to a file (covered in the "Saving Plots to Files" section). A higher DPI results in a higher-resolution image. You can set it alongside figsize
: plt.subplots(figsize=(8, 4), dpi=150)
.
Often, you need to display multiple plots side-by-side or in a grid to compare different views of your data or different datasets. Matplotlib makes this straightforward using subplots. The plt.subplots()
function is the preferred way to create a figure and a grid of subplots (Axes objects) simultaneously.
You pass the desired number of rows and columns to plt.subplots()
. It returns two things: the Figure
object and an array (or a single object if you only create one subplot) containing the Axes
objects for each subplot.
import matplotlib.pyplot as plt
import numpy as np
# Sample data
x = np.linspace(0, 2 * np.pi, 100)
y_sin = np.sin(x)
y_cos = np.cos(x)
y_tan = np.tan(x)
y_exp = np.exp(-x)
# Create a 2x2 grid of subplots
# figsize applies to the *entire* figure containing all subplots
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 8))
# axes is now a 2D NumPy array: [[ax1, ax2], [ax3, ax4]]
# Access individual axes using array indexing
# Top-left subplot
axes[0, 0].plot(x, y_sin, color='#4263eb') # Blue
axes[0, 0].set_title('Sine Wave')
axes[0, 0].set_ylabel('Amplitude')
axes[0, 0].grid(True, linestyle=':', alpha=0.6)
# Top-right subplot
axes[0, 1].plot(x, y_cos, color='#12b886') # Teal
axes[0, 1].set_title('Cosine Wave')
axes[0, 1].grid(True, linestyle=':', alpha=0.6)
# Bottom-left subplot
axes[1, 0].plot(x, y_tan, color='#f76707') # Orange
axes[1, 0].set_title('Tangent Wave (Limited y-range)')
axes[1, 0].set_ylim(-5, 5) # Limit y-axis for tangent
axes[1, 0].set_xlabel('Radians')
axes[1, 0].set_ylabel('Amplitude')
axes[1, 0].grid(True, linestyle=':', alpha=0.6)
# Bottom-right subplot
axes[1, 1].plot(x, y_exp, color='#ae3ec9') # Grape
axes[1, 1].set_title('Exponential Decay')
axes[1, 1].set_xlabel('Radians')
axes[1, 1].grid(True, linestyle=':', alpha=0.6)
# Display the figure with all subplots
plt.show() # plt.show() is called once for the entire figure
Notice how we accessed each subplot's Axes
object using indexing (e.g., axes[0, 0]
) and then called plotting methods (.plot()
, .set_title()
, etc.) on that specific Axes
object.
When subplots show related data, it's often useful to have them share the same x-axis or y-axis limits and ticks. This makes comparisons much easier. You can achieve this using the sharex
and sharey
arguments in plt.subplots()
.
import matplotlib.pyplot as plt
import numpy as np
# Sample data
years = np.arange(2010, 2021)
sales_a = np.random.rand(len(years)) * 100 + 50
sales_b = np.random.rand(len(years)) * 70 + 80
# Create a 2x1 grid, sharing the x-axis
fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(8, 6), sharex=True)
# Top subplot
axes[0].plot(years, sales_a, marker='o', linestyle='-', color='#228be6') # Blue
axes[0].set_title('Product A Sales')
axes[0].set_ylabel('Units Sold')
axes[0].grid(True, linestyle=':', alpha=0.6)
# Bottom subplot
axes[1].plot(years, sales_b, marker='s', linestyle='--', color='#51cf66') # Green
axes[1].set_title('Product B Sales')
axes[1].set_xlabel('Year')
axes[1].set_ylabel('Units Sold')
axes[1].grid(True, linestyle=':', alpha=0.6)
# Display the figure
plt.show()
In this example, sharex=True
ensures that both subplots have the same x-axis range and ticks. Notice that the x-axis labels and ticks only appear on the bottom-most plot, reducing redundancy. You could similarly use sharey=True
if the y-axes should be shared.
Sometimes, especially with multiple subplots, the default spacing might cause titles, axis labels, or tick labels to overlap. Matplotlib provides ways to adjust the padding between subplots.
tight_layout()
The simplest solution is often plt.tight_layout()
. Call this function after creating all your plots but before plt.show()
or saving the figure. It automatically adjusts subplot parameters to give specified padding, usually resulting in a clean layout without overlaps.
import matplotlib.pyplot as plt
import numpy as np
# Sample data
x = np.linspace(0, 10, 50)
# Create a 1x2 grid, potentially with overlapping elements initially
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 4))
axes[0].plot(x, np.sin(x), color='#7048e8') # Violet
axes[0].set_title('Sine Wave with a Long Title')
axes[0].set_xlabel('X Value')
axes[0].set_ylabel('Sine of X')
axes[1].plot(x, np.cos(x), color='#f06595') # Pink
axes[1].set_title('Cosine Wave with another Long Title')
axes[1].set_xlabel('X Value')
# axes[1].set_ylabel('Cosine of X') # Y label might overlap with left plot title without adjustment
# Apply tight_layout to adjust spacing
plt.tight_layout() # Call this before plt.show()
plt.show()
Without plt.tight_layout()
, the y-axis label of the right plot might overlap with the title of the left plot. Running plt.tight_layout()
usually fixes these issues nicely.
subplots_adjust()
For more precise control over spacing, you can use fig.subplots_adjust()
. This function allows you to manually set the padding around the subplots and the space between them. Common parameters include:
left
, right
, bottom
, top
: Define the boundaries of the subplots area as fractions of the figure width and height.wspace
: Width of the space between columns of subplots, as a fraction of the average axes width.hspace
: Height of the space between rows of subplots, as a fraction of the average axes height.import matplotlib.pyplot as plt
import numpy as np
# Sample data
x = np.linspace(0, 10, 50)
# Create a 2x1 grid
fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(6, 6))
axes[0].plot(x, np.sin(x), color='#15aabf') # Cyan
axes[0].set_title('Plot 1')
axes[1].plot(x, np.cos(x), color='#f59f00') # Yellow
axes[1].set_title('Plot 2')
axes[1].set_xlabel('X Value')
# Manually adjust spacing - increase space between rows
fig.subplots_adjust(hspace=0.5) # Increase vertical space
plt.show()
While subplots_adjust
offers fine control, tight_layout
is often sufficient and easier to use for common spacing issues, especially for beginners.
Seaborn functions are designed to work smoothly with Matplotlib's Figure and Axes objects. Most Seaborn plotting functions have an ax
parameter. You can create your figure layout using plt.subplots()
and then tell each Seaborn function exactly which Axes
object to draw its plot onto.
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
# Sample data in a Pandas DataFrame
data = pd.DataFrame({
'value': np.random.randn(200),
'category': np.random.choice(['A', 'B'], 200)
})
# Create a 1x2 layout using Matplotlib
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
# Use Seaborn to plot on the first Axes object
sns.histplot(data=data, x='value', ax=axes[0], color='#868e96') # Gray
axes[0].set_title('Histogram (Seaborn)')
# Use Seaborn to plot on the second Axes object
sns.boxplot(data=data, x='category', y='value', ax=axes[1], palette=['#91a7ff', '#ffc078']) # Indigo, Orange
axes[1].set_title('Box Plot by Category (Seaborn)')
# Improve layout
plt.tight_layout()
plt.show()
This approach gives you the power of Matplotlib's layout control combined with the statistical plotting capabilities and aesthetics of Seaborn.
By mastering figure size and subplot layout, you gain significant control over the presentation of your visualizations, allowing you to create clearer, more informative, and professionally arranged graphics.
© 2025 ApX Machine Learning