活动公告

系统通知
05-18 21:22
系统通知
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,资源失效请在帖子内回复要求补档,会尽快处理!
10-23 09:31

Matplotlib中文注释教程从入门到精通轻松解决图表中文显示与字体配置难题

SunJu_FaceMall

3万

主题

2860

科技点

3万

积分

白金月票

碾压王

积分
32872

塔罗立华奏

<font color=白金月票" /> 发表于 2025-9-14 09:20:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
前言

Matplotlib是Python中最常用的数据可视化库之一,但在处理中文注释时常常会遇到各种显示问题,如方块、乱码或缺失等现象。这些问题主要源于Matplotlib默认字体不支持中文字符。本文将从基础到进阶,全面讲解如何解决Matplotlib中的中文显示与字体配置问题,帮助您轻松掌握中文注释技巧。

一、Matplotlib中文显示问题的根源

1.1 字体支持问题

Matplotlib默认使用的字体(如DejaVu Sans、Arial等)大多是基于拉丁字母设计的,不包含中文字符。当尝试在这些字体中渲染中文时,就会出现无法显示的方块或问号。
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. # 生成示例数据
  4. x = np.linspace(0, 10, 100)
  5. y = np.sin(x)
  6. # 绘制图形 - 不设置中文字体
  7. plt.figure(figsize=(10, 6))
  8. plt.plot(x, y)
  9. plt.title("正弦函数图像")  # 中文标题
  10. plt.xlabel("x轴")         # 中文x轴标签
  11. plt.ylabel("y轴")         # 中文y轴标签
  12. plt.grid(True)
  13. plt.show()
复制代码

运行上述代码,您很可能会看到标题和坐标轴标签显示为方块或问号,这就是典型的中文显示问题。

1.2 编码问题

除了字体问题,编码问题也可能导致中文显示异常。虽然Python 3默认使用UTF-8编码,但在某些情况下,特别是在Windows系统中,如果系统编码设置不正确,也可能导致中文显示问题。

二、解决中文显示问题的基本方法

2.1 使用rcParams配置全局字体

Matplotlib的rcParams是一个全局配置字典,可以通过它来设置默认字体。这是一种简单直接的解决中文显示问题的方法。
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. # 设置中文字体
  4. plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
  5. plt.rcParams['axes.unicode_minus'] = False    # 用来正常显示负号
  6. # 生成示例数据
  7. x = np.linspace(0, 10, 100)
  8. y = np.sin(x)
  9. # 绘制图形
  10. plt.figure(figsize=(10, 6))
  11. plt.plot(x, y)
  12. plt.title("正弦函数图像")
  13. plt.xlabel("x轴")
  14. plt.ylabel("y轴")
  15. plt.grid(True)
  16. plt.show()
复制代码

在上述代码中,我们通过plt.rcParams['font.sans-serif'] = ['SimHei']将默认字体设置为黑体(SimHei),这样就能正常显示中文了。plt.rcParams['axes.unicode_minus'] = False是为了解决负号显示问题。

2.2 常用中文字体名称

不同的操作系统支持不同的中文字体,以下是一些常见的中文字体及其在Matplotlib中的名称:

2.3 针对特定文本对象设置字体

除了全局设置,我们还可以针对特定的文本对象(如标题、标签等)单独设置字体:
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from matplotlib.font_manager import FontProperties
  4. # 生成示例数据
  5. x = np.linspace(0, 10, 100)
  6. y = np.sin(x)
  7. # 定义字体
  8. font = FontProperties(fname=r"C:\Windows\Fonts\simhei.ttf", size=14)
  9. # 绘制图形
  10. plt.figure(figsize=(10, 6))
  11. plt.plot(x, y)
  12. plt.title("正弦函数图像", fontproperties=font)
  13. plt.xlabel("x轴", fontproperties=font)
  14. plt.ylabel("y轴", fontproperties=font)
  15. plt.grid(True)
  16. plt.show()
复制代码

这种方法更加灵活,可以为不同的文本元素设置不同的字体和大小。

三、字体配置的进阶技巧

3.1 查看系统可用字体

在配置中文字体之前,我们需要知道系统中有哪些字体可用。Matplotlib提供了查看系统字体的方法:
  1. from matplotlib.font_manager import fontManager
  2. # 获取所有字体名称
  3. font_names = [f.name for f in fontManager.ttflist]
  4. # 筛选中文字体
  5. chinese_fonts = [name for name in font_names if 'SimHei' in name or 'SimSun' in name or 'KaiTi' in name or
  6.                 'Microsoft YaHei' in name or 'PingFang' in name or 'Hiragino' in name or
  7.                 'WenQuanYi' in name or 'Noto Sans CJK' in name]
  8. print("系统中可用的中文字体:")
  9. for font in set(chinese_fonts):
  10.     print(font)
复制代码

3.2 使用FontProperties进行高级字体设置

FontProperties类提供了更丰富的字体设置选项:
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from matplotlib.font_manager import FontProperties
  4. # 生成示例数据
  5. x = np.linspace(0, 10, 100)
  6. y = np.sin(x)
  7. # 定义字体属性
  8. title_font = FontProperties(fname=r"C:\Windows\Fonts\simhei.ttf", size=16, weight='bold')
  9. label_font = FontProperties(fname=r"C:\Windows\Fonts\simhei.ttf", size=12)
  10. legend_font = FontProperties(fname=r"C:\Windows\Fonts\simkai.ttf", size=10)
  11. # 绘制图形
  12. plt.figure(figsize=(10, 6))
  13. plt.plot(x, y, label='正弦曲线')
  14. plt.title("正弦函数图像", fontproperties=title_font)
  15. plt.xlabel("x轴", fontproperties=label_font)
  16. plt.ylabel("y轴", fontproperties=label_font)
  17. plt.legend(prop=legend_font)
  18. plt.grid(True)
  19. plt.show()
复制代码

3.3 动态加载字体文件

如果系统中没有合适的中文字体,或者想要使用自定义字体,可以动态加载字体文件:
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from matplotlib.font_manager import FontProperties
  4. import matplotlib.font_manager as fm
  5. import os
  6. # 字体文件路径(可以是本地路径或网络路径)
  7. font_path = "path/to/your/chinese_font.ttf"
  8. # 如果字体文件不存在,可以下载一个
  9. if not os.path.exists(font_path):
  10.     # 这里以下载思源黑体为例
  11.     import urllib.request
  12.     url = "https://github.com/adobe-fonts/source-han-sans/releases/download/2.004R/SourceHanSansSC.zip"
  13.     urllib.request.urlretrieve(url, "SourceHanSansSC.zip")
  14.     # 解压并获取字体文件
  15.     # (实际使用时需要添加解压代码)
  16. # 加载字体
  17. font_prop = fm.FontProperties(fname=font_path)
  18. # 生成示例数据
  19. x = np.linspace(0, 10, 100)
  20. y = np.sin(x)
  21. # 绘制图形
  22. plt.figure(figsize=(10, 6))
  23. plt.plot(x, y)
  24. plt.title("正弦函数图像", fontproperties=font_prop)
  25. plt.xlabel("x轴", fontproperties=font_prop)
  26. plt.ylabel("y轴", fontproperties=font_prop)
  27. plt.grid(True)
  28. plt.show()
复制代码

四、不同操作系统的字体配置方案

4.1 Windows系统字体配置

Windows系统拥有丰富的中文字体资源,常见的配置方法如下:
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. # Windows系统下的中文字体配置
  4. plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei', 'SimSun']  # 按优先级尝试字体
  5. plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
  6. # 生成示例数据
  7. x = np.linspace(0, 10, 100)
  8. y = np.sin(x)
  9. # 绘制图形
  10. plt.figure(figsize=(10, 6))
  11. plt.plot(x, y)
  12. plt.title("正弦函数图像")
  13. plt.xlabel("x轴")
  14. plt.ylabel("y轴")
  15. plt.grid(True)
  16. plt.show()
复制代码

4.2 macOS系统字体配置

macOS系统也有优秀的中文字体,配置方法如下:
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. # macOS系统下的中文字体配置
  4. plt.rcParams['font.sans-serif'] = ['PingFang SC', 'Hiragino Sans GB', 'STHeiti']
  5. plt.rcParams['axes.unicode_minus'] = False
  6. # 生成示例数据
  7. x = np.linspace(0, 10, 100)
  8. y = np.sin(x)
  9. # 绘制图形
  10. plt.figure(figsize=(10, 6))
  11. plt.plot(x, y)
  12. plt.title("正弦函数图像")
  13. plt.xlabel("x轴")
  14. plt.ylabel("y轴")
  15. plt.grid(True)
  16. plt.show()
复制代码

4.3 Linux系统字体配置

Linux系统的中文字体配置相对复杂一些,通常需要先安装中文字体:
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. # Linux系统下的中文字体配置
  4. plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei', 'WenQuanYi Zen Hei', 'Noto Sans CJK SC']
  5. plt.rcParams['axes.unicode_minus'] = False
  6. # 生成示例数据
  7. x = np.linspace(0, 10, 100)
  8. y = np.sin(x)
  9. # 绘制图形
  10. plt.figure(figsize=(10, 6))
  11. plt.plot(x, y)
  12. plt.title("正弦函数图像")
  13. plt.xlabel("x轴")
  14. plt.ylabel("y轴")
  15. plt.grid(True)
  16. plt.show()
复制代码

4.4 跨平台字体配置方案

为了使代码在不同操作系统上都能正常工作,可以编写一个跨平台的字体配置函数:
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. import platform
  4. import matplotlib.font_manager as fm
  5. def setup_chinese_font():
  6.     """跨平台设置中文字体"""
  7.     system = platform.system()
  8.    
  9.     if system == 'Windows':
  10.         # Windows系统
  11.         chinese_fonts = ['Microsoft YaHei', 'SimHei', 'SimSun']
  12.     elif system == 'Darwin':
  13.         # macOS系统
  14.         chinese_fonts = ['PingFang SC', 'Hiragino Sans GB', 'STHeiti']
  15.     else:
  16.         # Linux系统
  17.         chinese_fonts = ['WenQuanYi Micro Hei', 'WenQuanYi Zen Hei', 'Noto Sans CJK SC']
  18.    
  19.     # 检查哪些字体可用
  20.     available_fonts = [f.name for f in fm.fontManager.ttflist]
  21.     font_to_use = None
  22.    
  23.     for font in chinese_fonts:
  24.         if font in available_fonts:
  25.             font_to_use = font
  26.             break
  27.    
  28.     if font_to_use:
  29.         plt.rcParams['font.sans-serif'] = [font_to_use]
  30.         plt.rcParams['axes.unicode_minus'] = False
  31.         print(f"已设置中文字体: {font_to_use}")
  32.         return True
  33.     else:
  34.         print("警告: 未找到合适的中文字体,中文可能无法正常显示")
  35.         return False
  36. # 设置中文字体
  37. setup_chinese_font()
  38. # 生成示例数据
  39. x = np.linspace(0, 10, 100)
  40. y = np.sin(x)
  41. # 绘制图形
  42. plt.figure(figsize=(10, 6))
  43. plt.plot(x, y)
  44. plt.title("正弦函数图像")
  45. plt.xlabel("x轴")
  46. plt.ylabel("y轴")
  47. plt.grid(True)
  48. plt.show()
复制代码

五、中文注释的各种技巧

5.1 图表标题和轴标签的中文注释

图表标题和轴标签是最常见的中文注释位置:
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from matplotlib.font_manager import FontProperties
  4. # 设置中文字体
  5. plt.rcParams['font.sans-serif'] = ['SimHei']
  6. plt.rcParams['axes.unicode_minus'] = False
  7. # 生成示例数据
  8. x = np.linspace(0, 10, 100)
  9. y1 = np.sin(x)
  10. y2 = np.cos(x)
  11. # 绘制图形
  12. plt.figure(figsize=(10, 6))
  13. plt.plot(x, y1, label='正弦函数')
  14. plt.plot(x, y2, label='余弦函数')
  15. plt.title("三角函数图像比较", fontsize=16)  # 设置标题和字体大小
  16. plt.xlabel("x轴(弧度)", fontsize=12)     # 设置x轴标签和字体大小
  17. plt.ylabel("y轴(函数值)", fontsize=12)   # 设置y轴标签和字体大小
  18. plt.legend(fontsize=12)                   # 设置图例字体大小
  19. plt.grid(True)
  20. plt.show()
复制代码

5.2 图例和文本注释的中文显示

图例和文本注释也是常用的中文注释位置:
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. # 设置中文字体
  4. plt.rcParams['font.sans-serif'] = ['SimHei']
  5. plt.rcParams['axes.unicode_minus'] = False
  6. # 生成示例数据
  7. x = np.linspace(0, 10, 100)
  8. y = np.sin(x)
  9. # 绘制图形
  10. plt.figure(figsize=(10, 6))
  11. plt.plot(x, y, label='正弦曲线')
  12. # 添加特殊点标记
  13. special_x = [np.pi/2, np.pi, 3*np.pi/2]
  14. special_y = [np.sin(val) for val in special_x]
  15. plt.scatter(special_x, special_y, color='red')
  16. # 添加文本注释
  17. for i, (xi, yi) in enumerate(zip(special_x, special_y)):
  18.     if i == 0:
  19.         plt.annotate(f'最大值点({xi:.2f}, {yi:.2f})',
  20.                     xy=(xi, yi),
  21.                     xytext=(xi+0.5, yi+0.2),
  22.                     arrowprops=dict(facecolor='black', shrink=0.05, width=1, headwidth=8))
  23.     elif i == 1:
  24.         plt.annotate(f'零点({xi:.2f}, {yi:.2f})',
  25.                     xy=(xi, yi),
  26.                     xytext=(xi+0.5, yi-0.5),
  27.                     arrowprops=dict(facecolor='black', shrink=0.05, width=1, headwidth=8))
  28.     else:
  29.         plt.annotate(f'最小值点({xi:.2f}, {yi:.2f})',
  30.                     xy=(xi, yi),
  31.                     xytext=(xi+0.5, yi+0.2),
  32.                     arrowprops=dict(facecolor='black', shrink=0.05, width=1, headwidth=8))
  33. plt.title("正弦函数图像及特殊点标注")
  34. plt.xlabel("x轴(弧度)")
  35. plt.ylabel("y轴(函数值)")
  36. plt.legend()
  37. plt.grid(True)
  38. plt.show()
复制代码

5.3 刻度标签的中文显示

有时候我们需要将刻度标签也设置为中文:
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. # 设置中文字体
  4. plt.rcParams['font.sans-serif'] = ['SimHei']
  5. plt.rcParams['axes.unicode_minus'] = False
  6. # 生成示例数据
  7. categories = ['第一季度', '第二季度', '第三季度', '第四季度']
  8. values = [120, 150, 180, 200]
  9. # 绘制柱状图
  10. plt.figure(figsize=(10, 6))
  11. bars = plt.bar(categories, values, color='skyblue')
  12. # 添加数值标签
  13. for bar in bars:
  14.     height = bar.get_height()
  15.     plt.text(bar.get_x() + bar.get_width()/2., height,
  16.              f'{height}万元',
  17.              ha='center', va='bottom')
  18. plt.title("季度销售额统计")
  19. plt.xlabel("季度")
  20. plt.ylabel("销售额(万元)")
  21. plt.grid(axis='y', linestyle='--', alpha=0.7)
  22. plt.show()
复制代码

5.4 复杂图表中的中文注释

在复杂图表中,我们可能需要在多个位置添加中文注释:
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from matplotlib.gridspec import GridSpec
  4. # 设置中文字体
  5. plt.rcParams['font.sans-serif'] = ['SimHei']
  6. plt.rcParams['axes.unicode_minus'] = False
  7. # 生成示例数据
  8. x = np.linspace(0, 10, 100)
  9. y1 = np.sin(x)
  10. y2 = np.cos(x)
  11. y3 = np.sin(x) * np.cos(x)
  12. # 创建复杂布局
  13. fig = plt.figure(figsize=(12, 10))
  14. gs = GridSpec(3, 2, figure=fig)
  15. # 第一个子图
  16. ax1 = fig.add_subplot(gs[0, :])
  17. ax1.plot(x, y1, 'r-', label='正弦函数')
  18. ax1.set_title('正弦函数图像', fontsize=14)
  19. ax1.set_ylabel('y值', fontsize=12)
  20. ax1.legend()
  21. ax1.grid(True)
  22. # 第二个子图
  23. ax2 = fig.add_subplot(gs[1, 0])
  24. ax2.plot(x, y2, 'g-', label='余弦函数')
  25. ax2.set_title('余弦函数图像', fontsize=14)
  26. ax2.set_xlabel('x值', fontsize=12)
  27. ax2.set_ylabel('y值', fontsize=12)
  28. ax2.legend()
  29. ax2.grid(True)
  30. # 第三个子图
  31. ax3 = fig.add_subplot(gs[1, 1])
  32. ax3.plot(x, y3, 'b-', label='正弦×余弦')
  33. ax3.set_title('正弦×余弦函数图像', fontsize=14)
  34. ax3.set_xlabel('x值', fontsize=12)
  35. ax3.set_ylabel('y值', fontsize=12)
  36. ax3.legend()
  37. ax3.grid(True)
  38. # 第四个子图(表格)
  39. ax4 = fig.add_subplot(gs[2, :])
  40. ax4.axis('off')
  41. # 创建表格数据
  42. cell_text = [
  43.     ['函数', '定义域', '值域', '奇偶性', '周期性'],
  44.     ['正弦函数', 'R', '[-1, 1]', '奇函数', '2π'],
  45.     ['余弦函数', 'R', '[-1, 1]', '偶函数', '2π'],
  46.     ['正弦×余弦', 'R', '[-0.5, 0.5]', '奇函数', 'π']
  47. ]
  48. # 添加表格
  49. table = ax4.table(cellText=cell_text, loc='center', cellLoc='center')
  50. table.auto_set_font_size(False)
  51. table.set_fontsize(12)
  52. table.scale(1, 2)
  53. # 设置表格样式
  54. for i in range(len(cell_text)):
  55.     for j in range(len(cell_text[0])):
  56.         if i == 0:  # 表头
  57.             table[(i, j)].set_facecolor('#40466e')
  58.             table[(i, j)].set_text_props(weight='bold', color='white')
  59.         else:
  60.             table[(i, j)].set_facecolor('#f5f5f5')
  61. # 添加总标题
  62. plt.suptitle('三角函数综合分析', fontsize=16, y=0.98)
  63. plt.tight_layout(rect=[0, 0, 1, 0.96])
  64. plt.show()
复制代码

六、实际案例分析与代码示例

6.1 数据分析报告中的中文图表

在数据分析报告中,我们经常需要创建包含中文的图表:
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. import pandas as pd
  4. # 设置中文字体
  5. plt.rcParams['font.sans-serif'] = ['SimHei']
  6. plt.rcParams['axes.unicode_minus'] = False
  7. # 创建示例数据
  8. np.random.seed(42)
  9. dates = pd.date_range(start='2023-01-01', end='2023-12-31', freq='M')
  10. sales = np.random.randint(80, 200, size=len(dates))
  11. profits = sales * np.random.uniform(0.1, 0.3, size=len(dates))
  12. # 创建DataFrame
  13. df = pd.DataFrame({
  14.     '日期': dates,
  15.     '销售额(万元)': sales,
  16.     '利润(万元)': profits
  17. })
  18. # 创建图表
  19. fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 10), sharex=True)
  20. # 销售额柱状图
  21. bars = ax1.bar(df['日期'], df['销售额(万元)'], color='skyblue', alpha=0.7)
  22. ax1.set_title('2023年月度销售额与利润分析', fontsize=16, pad=20)
  23. ax1.set_ylabel('销售额(万元)', fontsize=12)
  24. ax1.grid(axis='y', linestyle='--', alpha=0.7)
  25. # 添加销售额数值标签
  26. for bar in bars:
  27.     height = bar.get_height()
  28.     ax1.text(bar.get_x() + bar.get_width()/2., height,
  29.              f'{height}',
  30.              ha='center', va='bottom')
  31. # 利润折线图
  32. ax2.plot(df['日期'], df['利润(万元)'], 'ro-', linewidth=2, markersize=8)
  33. ax2.set_ylabel('利润(万元)', fontsize=12)
  34. ax2.set_xlabel('月份', fontsize=12)
  35. ax2.grid(axis='y', linestyle='--', alpha=0.7)
  36. # 添加利润数值标签
  37. for i, profit in enumerate(df['利润(万元)']):
  38.     ax2.text(df['日期'][i], profit, f'{profit:.1f}',
  39.              ha='center', va='bottom')
  40. # 添加平均利润线
  41. avg_profit = df['利润(万元)'].mean()
  42. ax2.axhline(y=avg_profit, color='green', linestyle='--', linewidth=1.5)
  43. ax2.text(df['日期'][0], avg_profit + 2, f'平均利润: {avg_profit:.1f}万元',
  44.          color='green', fontsize=10)
  45. # 添加总结文本
  46. total_sales = df['销售额(万元)'].sum()
  47. total_profit = df['利润(万元)'].sum()
  48. profit_margin = (total_profit / total_sales) * 100
  49. summary_text = f"年度总结:\n总销售额: {total_sales}万元\n总利润: {total_profit:.1f}万元\n利润率: {profit_margin:.1f}%"
  50. plt.figtext(0.15, 0.02, summary_text, fontsize=12,
  51.             bbox=dict(facecolor='white', alpha=0.8, boxstyle='round,pad=0.5'))
  52. plt.tight_layout(rect=[0, 0.05, 1, 0.95])
  53. plt.show()
复制代码

6.2 科学研究论文中的中文图表

科学研究论文中的图表通常需要更加精确和专业的注释:
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from matplotlib.font_manager import FontProperties
  4. # 设置中文字体
  5. plt.rcParams['font.sans-serif'] = ['SimHei']
  6. plt.rcParams['axes.unicode_minus'] = False
  7. # 生成示例数据
  8. np.random.seed(42)
  9. n_samples = 100
  10. x = np.linspace(0, 10, n_samples)
  11. y_true = 2 * x + 1 + np.random.normal(0, 2, n_samples)
  12. # 线性回归
  13. coefficients = np.polyfit(x, y_true, 1)
  14. polynomial = np.poly1d(coefficients)
  15. y_fit = polynomial(x)
  16. # 计算R²
  17. residuals = y_true - y_fit
  18. ss_res = np.sum(residuals**2)
  19. ss_tot = np.sum((y_true - np.mean(y_true))**2)
  20. r_squared = 1 - (ss_res / ss_tot)
  21. # 创建图表
  22. fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
  23. # 散点图与回归线
  24. ax1.scatter(x, y_true, alpha=0.6, label='观测数据')
  25. ax1.plot(x, y_fit, 'r-', linewidth=2, label=f'回归线: y = {coefficients[0]:.2f}x + {coefficients[1]:.2f}')
  26. ax1.set_title('线性回归分析', fontsize=14)
  27. ax1.set_xlabel('自变量 X', fontsize=12)
  28. ax1.set_ylabel('因变量 Y', fontsize=12)
  29. ax1.legend(fontsize=10)
  30. ax1.grid(True, linestyle='--', alpha=0.7)
  31. # 添加R²值
  32. ax1.text(0.05, 0.95, f'R² = {r_squared:.4f}', transform=ax1.transAxes,
  33.          fontsize=12, verticalalignment='top',
  34.          bbox=dict(boxstyle='round', facecolor='white', alpha=0.8))
  35. # 残差图
  36. ax2.scatter(x, residuals, alpha=0.6)
  37. ax2.axhline(y=0, color='r', linestyle='--')
  38. ax2.set_title('残差分析', fontsize=14)
  39. ax2.set_xlabel('自变量 X', fontsize=12)
  40. ax2.set_ylabel('残差', fontsize=12)
  41. ax2.grid(True, linestyle='--', alpha=0.7)
  42. # 添加残差统计信息
  43. residual_mean = np.mean(residuals)
  44. residual_std = np.std(residuals)
  45. ax2.text(0.05, 0.95, f'残差均值: {residual_mean:.4f}\n残差标准差: {residual_std:.4f}',
  46.          transform=ax2.transAxes, fontsize=10, verticalalignment='top',
  47.          bbox=dict(boxstyle='round', facecolor='white', alpha=0.8))
  48. # 添加总标题
  49. plt.suptitle('线性回归模型分析报告', fontsize=16, y=0.98)
  50. plt.tight_layout(rect=[0, 0, 1, 0.95])
  51. plt.show()
复制代码

6.3 交互式图表中的中文显示

使用Matplotlib创建交互式图表时,也需要注意中文显示问题:
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from matplotlib.widgets import Slider, Button
  4. # 设置中文字体
  5. plt.rcParams['font.sans-serif'] = ['SimHei']
  6. plt.rcParams['axes.unicode_minus'] = False
  7. # 创建图形和轴
  8. fig, ax = plt.subplots(figsize=(10, 6))
  9. plt.subplots_adjust(bottom=0.25)
  10. # 初始参数
  11. amplitude = 1.0
  12. frequency = 1.0
  13. phase = 0.0
  14. # 生成x值
  15. x = np.linspace(0, 10, 1000)
  16. # 绘制初始曲线
  17. line, = ax.plot(x, amplitude * np.sin(frequency * x + phase), lw=2)
  18. ax.set_title('正弦波参数调节器', fontsize=14)
  19. ax.set_xlabel('x轴', fontsize=12)
  20. ax.set_ylabel('y轴', fontsize=12)
  21. ax.grid(True)
  22. # 创建滑块轴
  23. ax_amp = plt.axes([0.25, 0.15, 0.65, 0.03])
  24. ax_freq = plt.axes([0.25, 0.1, 0.65, 0.03])
  25. ax_phase = plt.axes([0.25, 0.05, 0.65, 0.03])
  26. # 创建滑块
  27. amp_slider = Slider(
  28.     ax=ax_amp,
  29.     label='振幅',
  30.     valmin=0.1,
  31.     valmax=5.0,
  32.     valinit=amplitude,
  33. )
  34. freq_slider = Slider(
  35.     ax=ax_freq,
  36.     label='频率',
  37.     valmin=0.1,
  38.     valmax=5.0,
  39.     valinit=frequency,
  40. )
  41. phase_slider = Slider(
  42.     ax=ax_phase,
  43.     label='相位',
  44.     valmin=0.0,
  45.     valmax=2*np.pi,
  46.     valinit=phase,
  47. )
  48. # 更新函数
  49. def update(val):
  50.     amp = amp_slider.val
  51.     freq = freq_slider.val
  52.     phase = phase_slider.val
  53.     line.set_ydata(amp * np.sin(freq * x + phase))
  54.     fig.canvas.draw_idle()
  55. # 注册更新函数
  56. amp_slider.on_changed(update)
  57. freq_slider.on_changed(update)
  58. phase_slider.on_changed(update)
  59. # 重置按钮
  60. resetax = plt.axes([0.8, 0.01, 0.1, 0.03])
  61. button = Button(resetax, '重置', hovercolor='0.975')
  62. def reset(event):
  63.     amp_slider.reset()
  64.     freq_slider.reset()
  65.     phase_slider.reset()
  66. button.on_clicked(reset)
  67. plt.show()
复制代码

七、常见问题与解决方案

7.1 中文显示为方块或问号

问题现象:图表中的中文显示为方块或问号。

原因分析:Matplotlib使用的默认字体不支持中文字符。

解决方案:
  1. import matplotlib.pyplot as plt
  2. # 方法1:设置rcParams
  3. plt.rcParams['font.sans-serif'] = ['SimHei']  # 'SimHei'是黑体
  4. plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
  5. # 方法2:使用FontProperties
  6. from matplotlib.font_manager import FontProperties
  7. font = FontProperties(fname=r"C:\Windows\Fonts\simhei.ttf")  # Windows系统路径
  8. # font = FontProperties(fname="/System/Library/Fonts/PingFang.ttc")  # macOS系统路径
  9. # font = FontProperties(fname="/usr/share/fonts/truetype/wqy/wqy-microhei.ttc")  # Linux系统路径
  10. # 使用字体
  11. plt.title("中文标题", fontproperties=font)
复制代码

7.2 负号显示为方块

问题现象:图表中的负号显示为方块。

原因分析:某些中文字体不支持负号显示。

解决方案:
  1. import matplotlib.pyplot as plt
  2. # 解决负号显示问题
  3. plt.rcParams['axes.unicode_minus'] = False
  4. # 示例
  5. plt.figure(figsize=(8, 6))
  6. x = np.linspace(-5, 5, 100)
  7. y = x**2
  8. plt.plot(x, y)
  9. plt.title("二次函数图像")
  10. plt.xlabel("x轴")
  11. plt.ylabel("y轴")
  12. plt.grid(True)
  13. plt.show()
复制代码

7.3 字体文件路径问题

问题现象:指定字体文件路径时出现错误。

原因分析:字体文件路径不正确或字体文件不存在。

解决方案:
  1. import matplotlib.pyplot as plt
  2. from matplotlib.font_manager import FontProperties
  3. import os
  4. # 检查字体文件是否存在
  5. font_path = r"C:\Windows\Fonts\simhei.ttf"  # Windows系统路径
  6. # font_path = "/System/Library/Fonts/PingFang.ttc"  # macOS系统路径
  7. # font_path = "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc"  # Linux系统路径
  8. if os.path.exists(font_path):
  9.     font = FontProperties(fname=font_path)
  10.     print(f"成功加载字体: {font_path}")
  11. else:
  12.     print(f"字体文件不存在: {font_path}")
  13.     # 使用系统默认字体
  14.     plt.rcParams['font.sans-serif'] = ['SimHei']
  15.     font = None
  16. # 使用字体
  17. plt.figure(figsize=(8, 6))
  18. plt.plot([1, 2, 3], [4, 5, 6])
  19. if font:
  20.     plt.title("中文标题", fontproperties=font)
  21. else:
  22.     plt.title("中文标题")
  23. plt.show()
复制代码

7.4 保存图片时中文显示异常

问题现象:在图形窗口中中文显示正常,但保存为图片后中文显示异常。

原因分析:保存图片时使用的字体与显示时不同。

解决方案:
  1. import matplotlib.pyplot as plt
  2. from matplotlib.font_manager import FontProperties
  3. # 设置字体
  4. font_path = r"C:\Windows\Fonts\simhei.ttf"  # 替换为你的字体文件路径
  5. font = FontProperties(fname=font_path)
  6. # 创建图形
  7. plt.figure(figsize=(8, 6))
  8. plt.plot([1, 2, 3], [4, 5, 6])
  9. plt.title("中文标题", fontproperties=font)
  10. plt.xlabel("x轴", fontproperties=font)
  11. plt.ylabel("y轴", fontproperties=font)
  12. # 保存图片时指定字体
  13. plt.savefig("chinese_plot.png", dpi=300, bbox_inches='tight',
  14.             facecolor='white', edgecolor='none')
  15. plt.show()
复制代码

7.5 Jupyter Notebook中的中文显示问题

问题现象:在Jupyter Notebook中中文显示异常。

原因分析:Jupyter Notebook环境下的字体配置可能与本地环境不同。

解决方案:
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. # Jupyter Notebook中的中文字体设置
  4. %matplotlib inline
  5. plt.rcParams['font.sans-serif'] = ['SimHei']  # 或者其他支持中文的字体
  6. plt.rcParams['axes.unicode_minus'] = False
  7. # 示例
  8. plt.figure(figsize=(8, 6))
  9. x = np.linspace(0, 10, 100)
  10. y = np.sin(x)
  11. plt.plot(x, y)
  12. plt.title("正弦函数图像")
  13. plt.xlabel("x轴")
  14. plt.ylabel("y轴")
  15. plt.grid(True)
  16. plt.show()
复制代码

八、最佳实践与总结

8.1 中文字体配置的最佳实践

1. 使用跨平台字体配置:编写能够适应不同操作系统的字体配置代码,提高代码的可移植性。
  1. import matplotlib.pyplot as plt
  2. import platform
  3. import matplotlib.font_manager as fm
  4. def setup_chinese_font():
  5.     """跨平台设置中文字体"""
  6.     system = platform.system()
  7.    
  8.     if system == 'Windows':
  9.         chinese_fonts = ['Microsoft YaHei', 'SimHei', 'SimSun']
  10.     elif system == 'Darwin':
  11.         chinese_fonts = ['PingFang SC', 'Hiragino Sans GB', 'STHeiti']
  12.     else:
  13.         chinese_fonts = ['WenQuanYi Micro Hei', 'WenQuanYi Zen Hei', 'Noto Sans CJK SC']
  14.    
  15.     available_fonts = [f.name for f in fm.fontManager.ttflist]
  16.    
  17.     for font in chinese_fonts:
  18.         if font in available_fonts:
  19.             plt.rcParams['font.sans-serif'] = [font]
  20.             plt.rcParams['axes.unicode_minus'] = False
  21.             print(f"已设置中文字体: {font}")
  22.             return True
  23.    
  24.     print("警告: 未找到合适的中文字体")
  25.     return False
  26. # 使用函数设置中文字体
  27. setup_chinese_font()
复制代码

1. 创建字体配置模块:将字体配置代码封装为模块,在项目中重复使用。
  1. # chinese_font_config.py
  2. import matplotlib.pyplot as plt
  3. import platform
  4. import matplotlib.font_manager as fm
  5. import os
  6. class ChineseFontConfig:
  7.     def __init__(self):
  8.         self.font_set = False
  9.         self.font_name = None
  10.         self.font_path = None
  11.         self._setup_font()
  12.    
  13.     def _setup_font(self):
  14.         """设置中文字体"""
  15.         system = platform.system()
  16.         
  17.         if system == 'Windows':
  18.             chinese_fonts = ['Microsoft YaHei', 'SimHei', 'SimSun']
  19.             self.font_path = r"C:\Windows\Fonts\simhei.ttf"
  20.         elif system == 'Darwin':
  21.             chinese_fonts = ['PingFang SC', 'Hiragino Sans GB', 'STHeiti']
  22.             self.font_path = "/System/Library/Fonts/PingFang.ttc"
  23.         else:
  24.             chinese_fonts = ['WenQuanYi Micro Hei', 'WenQuanYi Zen Hei', 'Noto Sans CJK SC']
  25.             self.font_path = "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc"
  26.         
  27.         available_fonts = [f.name for f in fm.fontManager.ttflist]
  28.         
  29.         for font in chinese_fonts:
  30.             if font in available_fonts:
  31.                 plt.rcParams['font.sans-serif'] = [font]
  32.                 plt.rcParams['axes.unicode_minus'] = False
  33.                 self.font_set = True
  34.                 self.font_name = font
  35.                 print(f"已设置中文字体: {font}")
  36.                 return
  37.         
  38.         # 如果没有找到系统字体,尝试使用字体文件
  39.         if os.path.exists(self.font_path):
  40.             self.font_set = True
  41.             print(f"已使用字体文件: {self.font_path}")
  42.         else:
  43.             print("警告: 未找到合适的中文字体")
  44.    
  45.     def get_font_properties(self, size=12):
  46.         """获取字体属性"""
  47.         if self.font_set and self.font_path and os.path.exists(self.font_path):
  48.             return fm.FontProperties(fname=self.font_path, size=size)
  49.         return None
  50. # 使用示例
  51. # from chinese_font_config import ChineseFontConfig
  52. # font_config = ChineseFontConfig()
  53. # font_prop = font_config.get_font_properties(size=14)
复制代码

1. 使用相对路径或环境变量:当使用自定义字体文件时,使用相对路径或环境变量,提高代码的可移植性。
  1. import os
  2. from matplotlib.font_manager import FontProperties
  3. # 使用相对路径
  4. current_dir = os.path.dirname(os.path.abspath(__file__))
  5. font_path = os.path.join(current_dir, 'fonts', 'simhei.ttf')
  6. # 使用环境变量
  7. # font_path = os.environ.get('CHINESE_FONT_PATH', 'default_font_path')
  8. if os.path.exists(font_path):
  9.     font_prop = FontProperties(fname=font_path)
  10. else:
  11.     print(f"字体文件不存在: {font_path}")
  12.     font_prop = None
复制代码

8.2 中文注释的最佳实践

1. 保持一致性:在整个图表或报告中使用一致的字体和样式。
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from matplotlib.font_manager import FontProperties
  4. # 设置统一的字体
  5. font_path = r"C:\Windows\Fonts\simhei.ttf"
  6. title_font = FontProperties(fname=font_path, size=16, weight='bold')
  7. label_font = FontProperties(fname=font_path, size=12)
  8. legend_font = FontProperties(fname=font_path, size=10)
  9. tick_font = FontProperties(fname=font_path, size=10)
  10. # 创建图表
  11. plt.figure(figsize=(10, 6))
  12. x = np.linspace(0, 10, 100)
  13. y = np.sin(x)
  14. plt.plot(x, y, label='正弦函数')
  15. # 应用统一的字体样式
  16. plt.title("正弦函数图像", fontproperties=title_font)
  17. plt.xlabel("x轴", fontproperties=label_font)
  18. plt.ylabel("y轴", fontproperties=label_font)
  19. plt.legend(prop=legend_font)
  20. # 设置刻度标签字体
  21. plt.xticks(fontproperties=tick_font)
  22. plt.yticks(fontproperties=tick_font)
  23. plt.grid(True)
  24. plt.show()
复制代码

1. 合理使用字体大小:根据图表元素的重要性设置不同的字体大小,创建视觉层次。
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from matplotlib.font_manager import FontProperties
  4. # 设置中文字体
  5. plt.rcParams['font.sans-serif'] = ['SimHei']
  6. plt.rcParams['axes.unicode_minus'] = False
  7. # 创建图表
  8. fig, ax = plt.subplots(figsize=(12, 8))
  9. # 生成数据
  10. categories = ['产品A', '产品B', '产品C', '产品D', '产品E']
  11. values1 = [25, 35, 30, 20, 40]
  12. values2 = [20, 30, 25, 25, 35]
  13. # 绘制柱状图
  14. bar_width = 0.35
  15. x = np.arange(len(categories))
  16. bars1 = ax.bar(x - bar_width/2, values1, bar_width, label='2022年')
  17. bars2 = ax.bar(x + bar_width/2, values2, bar_width, label='2023年')
  18. # 设置标题和标签(较大的字体)
  19. ax.set_title('产品销售对比分析', fontsize=16, pad=20)
  20. ax.set_xlabel('产品类别', fontsize=14)
  21. ax.set_ylabel('销售额(万元)', fontsize=14)
  22. # 设置刻度标签(中等字体)
  23. ax.set_xticks(x)
  24. ax.set_xticklabels(categories, fontsize=12)
  25. ax.tick_params(axis='y', labelsize=12)
  26. # 设置图例(中等字体)
  27. ax.legend(fontsize=12)
  28. # 添加数值标签(较小的字体)
  29. for bars in [bars1, bars2]:
  30.     for bar in bars:
  31.         height = bar.get_height()
  32.         ax.text(bar.get_x() + bar.get_width()/2., height,
  33.                 f'{height}',
  34.                 ha='center', va='bottom', fontsize=10)
  35. # 添加注释文本(较小的字体)
  36. ax.text(0.02, 0.95, '数据来源: 公司销售部门',
  37.         transform=ax.transAxes, fontsize=10,
  38.         verticalalignment='top')
  39. ax.grid(axis='y', linestyle='--', alpha=0.7)
  40. plt.tight_layout()
  41. plt.show()
复制代码

1. 注意可读性:确保中文注释清晰可读,避免文字重叠或过于拥挤。
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from matplotlib.font_manager import FontProperties
  4. # 设置中文字体
  5. plt.rcParams['font.sans-serif'] = ['SimHei']
  6. plt.rcParams['axes.unicode_minus'] = False
  7. # 创建图表
  8. fig, ax = plt.subplots(figsize=(12, 8))
  9. # 生成数据
  10. np.random.seed(42)
  11. data = np.random.normal(0, 1, 100)
  12. # 绘制直方图
  13. n, bins, patches = ax.hist(data, bins=20, density=True, alpha=0.7, color='skyblue')
  14. # 添加正态分布曲线
  15. mu, sigma = np.mean(data), np.std(data)
  16. x = np.linspace(min(data), max(data), 100)
  17. y = 1/(sigma * np.sqrt(2 * np.pi)) * np.exp(- (x - mu)**2 / (2 * sigma**2))
  18. ax.plot(x, y, 'r-', linewidth=2, label='正态分布曲线')
  19. # 设置标题和标签
  20. ax.set_title('数据分布分析', fontsize=16, pad=20)
  21. ax.set_xlabel('数值', fontsize=14)
  22. ax.set_ylabel('密度', fontsize=14)
  23. # 添加统计信息文本框
  24. stats_text = f'样本数: {len(data)}\n均值: {mu:.2f}\n标准差: {sigma:.2f}'
  25. props = dict(boxstyle='round', facecolor='white', alpha=0.8)
  26. ax.text(0.05, 0.95, stats_text, transform=ax.transAxes, fontsize=12,
  27.         verticalalignment='top', bbox=props)
  28. # 添加峰值标注
  29. peak_idx = np.argmax(n)
  30. peak_x = (bins[peak_idx] + bins[peak_idx+1]) / 2
  31. peak_y = n[peak_idx]
  32. ax.annotate(f'峰值: ({peak_x:.2f}, {peak_y:.2f})',
  33.             xy=(peak_x, peak_y),
  34.             xytext=(peak_x+0.5, peak_y+0.02),
  35.             arrowprops=dict(facecolor='black', shrink=0.05, width=1, headwidth=8),
  36.             fontsize=12)
  37. # 设置图例
  38. ax.legend(fontsize=12)
  39. # 调整布局,确保所有文本元素清晰可见
  40. plt.tight_layout()
  41. plt.show()
复制代码

8.3 总结

Matplotlib中文注释和字体配置是数据可视化中的重要环节。通过本文的介绍,我们了解了:

1. 中文显示问题的根源在于字体不支持中文字符。
2. 解决中文显示问题的基本方法包括使用rcParams配置全局字体和针对特定文本对象设置字体。
3. 不同操作系统有不同的字体配置方案,编写跨平台代码可以提高可移植性。
4. 中文注释可以应用于图表标题、轴标签、图例、文本注释等多个位置。
5. 实际案例中,我们需要根据具体需求选择合适的字体配置方案。
6. 常见问题如中文显示为方块、负号显示异常等都有相应的解决方案。
7. 遵循最佳实践,如保持字体一致性、合理使用字体大小、注意可读性等,可以创建更加专业和美观的中文图表。

掌握Matplotlib中文注释和字体配置技巧,将帮助您在数据可视化工作中更加得心应手,创建出既美观又实用的图表。希望本文能够成为您解决Matplotlib中文显示问题的实用指南。
「七転び八起き(ななころびやおき)」
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则