如何调整分组箱线图的尺寸以清晰显示标签?
The Problem
I'm using the following code to create a grouped boxplot with Seaborn and Matplotlib:
import matplotlib.pyplot as plt import seaborn as sns import pandas as pd import os import matplotlib.font_manager as font_manager import sys import numpy as np import matplotlib as mpl path = os.getcwd() + "/results/" sns.set_theme(style="whitegrid") df = pd.read_csv("C:/tmp/all2.txt") ax = sns.boxplot(x="cluster", y="val", hue="type", palette=["k", "w"], data=df,showfliers = False) #sns.despine(ax=ax, trim=True, offset={'left':1,'right':1,'top':1,'bottom':1}) ax.set(ylabel='Number', xlabel='Clustered profiles') font = font_manager.FontProperties(family='sans-serif', weight='bold', style='normal') plt.legend(loc='best', frameon=False, prop=font) plt.legend(loc='best', frameon=False, prop=font) plt.xticks(weight='bold', fontname='sans-serif') plt.yticks(weight='bold', fontname='sans-serif') plt.xlabel("Clustered profiles", weight='bold', fontname='sans-serif', size=14) plt.tight_layout() plt.savefig(path + "/myoutput.pdf", dpi=250, transparent=False, bbox_inches='tight', format="pdf")Some labels in the generated plot are unreadable. I tried increasing the dpi when saving, but it didn't help. What settings am I missing?
Solutions to Fix Blurry Labels
Let's walk through the key adjustments to make your labels sharp and readable:
1. Set Global Font & Rendering Defaults
Blurry text often comes from small default font sizes or disabled anti-aliasing. Add these lines at the start of your script to configure global Matplotlib settings:
# Configure global matplotlib settings for better text rendering mpl.rcParams['font.size'] = 12 # Base font size for all elements mpl.rcParams['axes.labelsize'] = 14 # Default axis label size mpl.rcParams['xtick.labelsize'] = 12 # X-axis tick label size mpl.rcParams['ytick.labelsize'] = 12 # Y-axis tick label size mpl.rcParams['text.antialiased'] = True # Enable anti-aliasing for smoother text
2. Remove Duplicate Legend Calls
You’re calling plt.legend() twice, which is redundant and can cause unexpected behavior. Replace both calls with a single, properly configured legend:
# Single legend call with explicit font settings plt.legend( loc='best', frameon=False, prop={'family':'sans-serif', 'weight':'bold', 'size':12} )
3. Standardize Font Sizes for All Text Elements
Your current code sets the x-label size to 14 but leaves the y-label and tick labels without explicit size settings. Update these to ensure consistency:
# Set axis labels with matching size and weight plt.xlabel("Clustered profiles", weight='bold', fontname='sans-serif', size=14) plt.ylabel("Number", weight='bold', fontname='sans-serif', size=14) # Set tick labels with explicit font size plt.xticks(weight='bold', fontname='sans-serif', fontsize=12) plt.yticks(weight='bold', fontname='sans-serif', fontsize=12)
4. Verify Font Availability
If the sans-serif font family isn’t mapped to a clear, readable font on your system, labels might render poorly. Try specifying a specific font like Arial (if available on your machine):
font = font_manager.FontProperties(family='Arial', weight='bold', style='normal', size=12)
5. Understand Vector vs. Raster Output
Since you’re saving as a PDF (a vector format), increasing DPI won’t improve text sharpness—vector graphics scale infinitely without losing quality. The core issue is text size, not resolution. Focus on adjusting font sizes rather than DPI for PDF outputs.
Revised Full Code
Here’s the complete updated code incorporating all fixes:
import matplotlib.pyplot as plt import seaborn as sns import pandas as pd import os import matplotlib.font_manager as font_manager import numpy as np import matplotlib as mpl # Configure global matplotlib settings for sharp, readable text mpl.rcParams['font.size'] = 12 mpl.rcParams['axes.labelsize'] = 14 mpl.rcParams['xtick.labelsize'] = 12 mpl.rcParams['ytick.labelsize'] = 12 mpl.rcParams['text.antialiased'] = True path = os.getcwd() + "/results/" sns.set_theme(style="whitegrid") df = pd.read_csv("C:/tmp/all2.txt") ax = sns.boxplot( x="cluster", y="val", hue="type", palette=["k", "w"], data=df, showfliers=False ) # Set axis labels with consistent styling plt.xlabel("Clustered profiles", weight='bold', fontname='sans-serif', size=14) plt.ylabel("Number", weight='bold', fontname='sans-serif', size=14) # Configure legend with proper font settings plt.legend( loc='best', frameon=False, prop={'family':'sans-serif', 'weight':'bold', 'size':12} ) # Style tick labels plt.xticks(weight='bold', fontname='sans-serif', fontsize=12) plt.yticks(weight='bold', fontname='sans-serif', fontsize=12) plt.tight_layout() # Save as PDF (vector format) – high DPI isn't necessary here plt.savefig( path + "/myoutput.pdf", transparent=False, bbox_inches='tight', format="pdf" )
内容的提问来源于stack exchange,提问作者Cenk Ten

