如何在指定尺寸PDF中导出固定自定义尺寸的Matplotlib绘图并居中显示
I get exactly what you're asking for—you want your 8x6 inch plot to stay exactly that size, no scaling, and sit neatly in the center of an A4 (or A3, custom) PDF page. Let's break down how to fix this, since the default savefig behavior can be tricky with paper sizes.
Core Idea
Instead of letting matplotlib scale your plot to fit the paper, we'll create a PDF page matching your target paper size, then place your fixed-size plot directly in the center by calculating the correct margins automatically.
Modified Code
Here's your updated code with the fix applied. I've added comments to highlight the key changes:
import pandas as pd import matplotlib.pyplot as plt from IPython.core.display import Image, display from matplotlib.backends.backend_pdf import PdfPages from natsort import os_sorted import os import glob import re # -------------------------- # New: Define paper and plot dimensions (in inches) # -------------------------- # A4 dimensions (inches): 8.27 width, 11.69 height # A3 dimensions (inches): 11.69 width, 16.53 height # Replace these values for custom paper sizes paper_width = 8.27 paper_height = 11.69 # Your fixed plot size plot_width = 8 plot_height = 6 # Calculate margins to center the plot left_margin = (paper_width - plot_width) / 2 bottom_margin = (paper_height - plot_height) / 2 # Convert margins to relative coordinates (0-1 scale for the figure) rel_left = left_margin / paper_width rel_bottom = bottom_margin / paper_height rel_width = plot_width / paper_width rel_height = plot_height / paper_height # use glob to get all the csv files # in the folder path = r'D:\LD25\VMT processed\Donaldson_Point_20210120\excel data' # January adcp obs data #path = r'D:\LD25\VMT processed\Donaldson_Point_20210308\excel data' # March adcp obs data obs_files = glob.glob(os.path.join(path, "*.xlsx")) obs_files = os_sorted(obs_files) sim = pd.read_excel(r'D:\LD25\ADH simulated\adh_simulated_Jan.xlsx','Sheet1') # January sim data #sim = pd.read_excel(r'D:\LD25\ADH simulated\adh_simulated_March.xlsx','Sheet1') # March sim data pdf = PdfPages(r'C:\Users\clhal\.spyder-py3\python adcp calibration\pdf\Angle_.pdf') for i,f in enumerate(obs_files): # i=count, f=value/name # -------------------------- # Modified: Create figure matching paper size, then add fixed-size subplot # -------------------------- # Create figure with exact paper dimensions fig = plt.figure(figsize=(paper_width, paper_height)) # Add your fixed-size plot, centered on the figure ax = fig.add_axes([rel_left, rel_bottom, rel_width, rel_height]) plt.rcParams.update({'font.size': 12}) # read the csv file obs = pd.read_excel(f,'Smoothed_Planview') list(sim) ax.plot(obs['Distance, in meters'],obs['Velocity direction, in deg. from true north']) #ax.plot(sim.iloc[:,2*i],sim.iloc[:,2*i+1]) ax.set_title('Jan, Transect %d' %(i+1)) #ax.set_title('March, Transect %d' %(i+1)) ax.set_xlabel("Distance (m)") # Fixed typo: was "m/s" but distance is meters ax.set_ylabel(" Direction (degree)") # print the location and filename print('Location:', f) print('File Name:', f.split("\\")[-1]) # print the content print('Content:') display(sim) print() # -------------------------- # Modified: Save without scaling (bbox_inches removed to keep fixed size) # -------------------------- pdf.savefig(fig, pad_inches=0) # No padding needed—we calculated margins manually plt.savefig(r"C:\Users\clhal\.spyder-py3\python adcp calibration\pdf\tran_{0}.png".format(i+1),dpi=300) plt.close(fig) # Important to close figures to save memory pdf.close()
Key Changes Explained
- Paper & Plot Dimensions: We explicitly define the target paper size (A4 here) and your fixed plot size. This lets us calculate exact margins to center the plot.
- Centered Subplot: Instead of using
plt.subplots(), we create a figure matching the paper size, then usefig.add_axes()to place your 8x6 plot in the center. The[rel_left, rel_bottom, rel_width, rel_height]values ensure it's perfectly centered. - Save Without Scaling: We removed
bbox_inches='tight'because that can stretch your plot to fit the page. Instead, our manual margin calculation ensures the plot stays fixed size and centered. - Memory Management: Added
plt.close(fig)to avoid memory leaks when processing multiple files.
Adapting to Other Paper Sizes
- For A3: Change
paper_width = 11.69andpaper_height = 16.53 - For Letter: Use
paper_width = 8.5,paper_height = 11 - For custom sizes: Just plug in your desired width/height in inches (matplotlib uses inches by default for
figsize).
This approach guarantees your plot never scales—its dimensions stay 8x6 inches regardless of the PDF paper size, and it's always centered neatly.
内容的提问来源于stack exchange,提问作者ZVY545

