thermoelasticsim.utils.plot_config 源代码

#!/usr/bin/env python3
"""matplotlib字体配置模块

一劳永逸解决中文字体显示问题

Usage:
    import matplotlib.pyplot as plt
    from thermoelasticsim.utils.plot_config import setup_matplotlib
    setup_matplotlib()  # 之后就可以正常使用中文

    # 或者直接导入已配置的pyplot
    from thermoelasticsim.utils.plot_config import plt

Created: 2025-08-17
"""

import platform

import matplotlib

# 使用Agg后端,避免GUI问题
matplotlib.use("Agg")
import matplotlib.pyplot as plt


def get_system_fonts():
    """获取系统可用的中文字体"""
    system = platform.system()

    if system == "Darwin":  # macOS
        fonts = [
            "Arial Unicode MS",  # macOS内置中文字体
            "PingFang SC",  # macOS系统字体
            "STHeiti",  # 华文黑体
            "Hiragino Sans GB",  # 冬青黑体
            "STSong",  # 华文宋体
            "SimHei",  # 黑体
            "SimSun",  # 宋体
            "DejaVu Sans",  # 后备字体
            "Arial",  # 最终后备
        ]
    elif system == "Windows":
        fonts = [
            "Microsoft YaHei",  # 微软雅黑
            "SimHei",  # 黑体
            "SimSun",  # 宋体
            "KaiTi",  # 楷体
            "FangSong",  # 仿宋
            "DejaVu Sans",  # 后备字体
            "Arial",  # 最终后备
        ]
    else:  # Linux
        fonts = [
            "Noto Sans CJK SC",  # Google字体
            "WenQuanYi Micro Hei",  # 文泉驿微米黑
            "WenQuanYi Zen Hei",  # 文泉驿正黑
            "Droid Sans Fallback",  # Android字体
            "AR PL UMing CN",  # 文鼎字体
            "DejaVu Sans",  # 后备字体
            "Liberation Sans",  # 最终后备
        ]

    return fonts


def test_font_availability(fonts):
    """测试字体可用性"""
    from matplotlib.font_manager import FontProperties

    available_fonts = []
    for font in fonts:
        try:
            fp = FontProperties(family=font)
            # 尝试创建一个简单的图来测试字体
            fig, ax = plt.subplots(figsize=(1, 1))
            ax.text(0.5, 0.5, "测试", fontproperties=fp)
            plt.close(fig)
            available_fonts.append(font)
            break  # 找到第一个可用字体就停止
        except Exception:
            continue

    return available_fonts


[文档] def setup_matplotlib(force_english=False): """ 设置matplotlib的字体配置 Parameters ---------- force_english : bool 是否强制使用英文字体(当中文字体有问题时) """ if force_english: # 强制使用英文字体 plt.rcParams["font.family"] = ["DejaVu Sans", "Arial", "Liberation Sans"] plt.rcParams["axes.unicode_minus"] = False print("INFO: 使用英文字体配置") return try: # 获取系统字体列表 system_fonts = get_system_fonts() # 设置字体优先级 plt.rcParams["font.sans-serif"] = system_fonts plt.rcParams["font.family"] = "sans-serif" plt.rcParams["axes.unicode_minus"] = False # 正确显示负号 # 其他常用配置 plt.rcParams["figure.figsize"] = (10, 8) plt.rcParams["figure.dpi"] = 100 plt.rcParams["savefig.dpi"] = 300 plt.rcParams["savefig.bbox"] = "tight" plt.rcParams["savefig.pad_inches"] = 0.1 # 测试中文字体 fig, ax = plt.subplots(figsize=(1, 1)) ax.text(0.5, 0.5, "中文测试", fontsize=12) plt.close(fig) print(f"INFO: 字体配置成功,优先使用: {system_fonts[0]}") except Exception as e: # 字体配置失败,回退到英文 plt.rcParams["font.family"] = ["DejaVu Sans", "Arial", "Liberation Sans"] plt.rcParams["axes.unicode_minus"] = False print(f"WARNING: 中文字体配置失败 ({e}),回退到英文字体")
[文档] def get_chinese_font(): """获取第一个可用的中文字体名称""" system_fonts = get_system_fonts() available = test_font_availability(system_fonts) return available[0] if available else "DejaVu Sans"
# 自动设置字体 setup_matplotlib() # 导出配置好的pyplot,可以直接导入使用 __all__ = ["setup_matplotlib", "get_chinese_font", "plt"]