Warning (from warnings module): File "C:\Users\白子健\Desktop\2.py", line 473 self.canvas.draw() UserWarning: Glyph 36724 (\N{CJK UNIFIED IDEOGRAPH-8F74}) missing from font(s) DejaVu Sans. Warning (from warnings module): File "C:\Users\白子健\Desktop\2.py", line 473 self.canvas.draw() UserWarning: Glyph 21521 (\N{CJK UNIFIED IDEOGRAPH-5411}) missing from font(s) DejaVu Sans. Warning (from warnings module): File "C:\Users\白子健\Desktop\2.py", line 473 self.canvas.draw() UserWarning: Glyph 20896 (\N{CJK UNIFIED IDEOGRAPH-51A0}) missing from font(s) DejaVu Sans. Warning (from warnings module): File "C:\Users\白子健\Desktop\2.py", line 473 self.canvas.draw() UserWarning: Glyph 29366 (\N{CJK UNIFIED IDEOGRAPH-72B6}) missing from font(s) DejaVu Sans. Warning (from warnings module): File "C:\Users\白子健\Desktop\2.py", line 473 self.canvas.draw() UserWarning: Glyph 30690 (\N{CJK UNIFIED IDEOGRAPH-77E2}) missing from font(s) DejaVu Sans. Warning (from warnings module): File "C:\Users\白子健\Desktop\2.py", line 458 self.canvas.draw() UserWarning: Glyph 36724 (\N{CJK UNIFIED IDEOGRAPH-8F74}) missing from font(s) DejaVu Sans. Warning (from warnings module): File "C:\Users\白子健\Desktop\2.py", line 458 self.canvas.draw() UserWarning: Glyph 21521 (\N{CJK UNIFIED IDEOGRAPH-5411}) missing from font(s) DejaVu Sans. Warning (from warnings module): File "C:\Users\白子健\Desktop\2.py", line 458 self.canvas.draw() UserWarning: Glyph 20896 (\N{CJK UNIFIED IDEOGRAPH-51A0}) missing from font(s) DejaVu Sans. Warning (from warnings module): File "C:\Users\白子健\Desktop\2.py", line 458 self.canvas.draw() UserWarning: Glyph 29366 (\N{CJK UNIFIED IDEOGRAPH-72B6}) missing from font(s) DejaVu Sans. Warning (from warnings module): File "C:\Users\白子健\Desktop\2.py", line 458 self.canvas.draw() UserWarning: Glyph 30690 (\N{CJK UNIFIED IDEOGRAPH-77E2}) missing from font(s) DejaVu Sans. 出现报错,但模型显示正常是什么原因
时间: 2025-07-22 13:40:43 浏览: 4
<think>我们遇到了Matplotlib中文字体缺失的问题。根据引用[2]和引用[3],我们可以通过设置中文字体来解决这个问题。具体来说,我们需要设置Matplotlib的字体参数,使用支持中文的字体(如SimHei)并确保负号正常显示。
在代码中,我们已经尝试设置了中文字体,但可能由于系统环境不同,字体设置可能未生效。我们可以尝试以下步骤:
1. 确保系统中存在所需的中文字体(如SimHei)。对于Linux系统,可能需要额外安装中文字体包;Windows系统通常自带。
2. 在代码中明确设置字体,并确保在创建Figure之前设置。
根据引用[3],我们可以在代码开头设置:
```python
from pylab import mpl
mpl.rcParams["font.sans-serif"] = ["SimHei"] # 设置黑体
mpl.rcParams["axes.unicode_minus"] = False # 解决负号显示问题
```
但是,我们也可以使用`matplotlib`的`rcParams`来设置,如引用[2]所示。
在用户代码中,已经使用了:
```python
import matplotlib.pyplot as plt
from matplotlib import rcParams
rcParams['font.sans-serif'] = ['SimHei']
rcParams['axes.unicode_minus'] = False
```
但是,仍然出现警告,说明字体设置可能没有正确应用到所有文本上。我们可以尝试以下方法:
- 使用`plt.rcParams`代替`rcParams`,确保全局设置。
- 检查系统中是否存在SimHei字体,或者尝试其他中文字体(如Microsoft YaHei, SimSun等)。
此外,还可以尝试使用`font_manager`来指定字体文件路径,确保字体被正确加载。
具体步骤:
1. 导入字体管理器:
```python
from matplotlib.font_manager import FontProperties
```
2. 指定中文字体文件路径(如果知道具体路径)或者使用字体名称。
但是,在跨平台时,更可靠的方法是使用字体名称,并确保该字体在系统中可用。
另一种方法:使用`font_manager`的`FontProperties`来为每个文本元素单独设置字体,但这比较繁琐。
我们尝试在代码中全局设置,并确保在绘图之前设置。
在用户提供的代码中,我们已经在`init_ui`方法中创建了`FigureCanvas`,而设置字体的代码可能是在创建之后才执行?所以需要确保在导入matplotlib后立即设置。
修改:在程序的最开始(导入模块后)就设置字体。
由于我们使用的是PyQt5,并且代码结构是:先导入各种模块,然后定义类。我们可以在导入模块后立即设置matplotlib的全局字体。
具体修改:
在代码开头,在导入`matplotlib.pyplot`之后,立即设置rcParams。
例如:
```python
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置黑体
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
```
但是,请注意,在代码中我们使用了`from matplotlib import rcParams`,然后设置`rcParams`,这与`plt.rcParams`是等价的。
因此,我们可以在整个模块的最开始,在导入`plt`之后,立即设置这些参数。
另外,如果系统中没有SimHei字体,我们可以尝试使用其他字体,或者使用`font_manager`来添加字体。
由于我们无法确定用户系统环境,我们可以尝试捕获警告,或者使用更通用的方法:使用`font_manager`查找可用中文字体。
我们可以这样:
```python
import matplotlib as mpl
from matplotlib.font_manager import FontManager
# 获取所有可用字体
fm = FontManager()
available_fonts = [f.name for f in fm.ttflist]
# 打印可用中文字体,或者设置一个已知的中文字体列表,然后选择第一个可用的
chinese_fonts = ['SimHei', 'Microsoft YaHei', 'SimSun', 'KaiTi', 'FangSong', 'STSong', 'STKaiti', 'STXihei', 'STHeiti']
selected_font = None
for font in chinese_fonts:
if any(f.lower() == font.lower() for f in available_fonts):
selected_font = font
break
if selected_font:
mpl.rcParams['font.sans-serif'] = [selected_font]
mpl.rcParams['axes.unicode_minus'] = False
else:
print("Warning: No Chinese font found. Chinese characters may not display correctly.")
```
但是,这种方法可能会在每次运行时都检查,并且如果字体列表很大,可能会影响启动速度。因此,我们可以只在第一次运行时检查并设置。
考虑到我们的代码是一个GUI程序,启动速度很重要,我们可以简化:只设置一种字体,如果该字体不存在,则使用默认字体(可能会显示方框),或者提示用户安装字体。
在代码中,我们决定采用以下方式:
在程序的最开始(在导入模块之后),设置中文字体,并忽略警告(因为如果字体不存在,我们无法显示中文,但至少程序可以运行)。
但是,用户报告中已经出现了警告,说明字体设置没有生效。因此,我们尝试使用更直接的方法:指定字体文件。
如果我们的程序打包时包含一个中文字体文件(如simhei.ttf),我们可以使用绝对路径加载字体。
例如:
```python
import matplotlib as mpl
from matplotlib.font_manager import FontProperties, fontManager
# 假设字体文件在程序所在目录的fonts目录下
font_path = os.path.join(os.path.dirname(__file__), 'fonts', 'simhei.ttf')
if os.path.exists(font_path):
fontManager.addfont(font_path)
prop = FontProperties(fname=font_path)
mpl.rcParams['font.family'] = 'sans-serif'
mpl.rcParams['font.sans-serif'] = [prop.get_name()]
mpl.rcParams['axes.unicode_minus'] = False
else:
# 尝试使用系统字体
try:
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
except:
pass
```
但是,由于我们无法控制用户的环境,且用户可能没有安装SimHei,我们建议在代码中嵌入字体文件(如果程序是打包分发的话)。
在当前的代码中,我们暂时不采用嵌入字体文件的方式,而是采用以下方法:
1. 在程序开头设置默认使用SimHei,并忽略警告。
2. 如果用户环境没有该字体,则显示英文。
但是,用户要求显示中文,所以我们需要确保中文字体可用。
由于原问题是在使用Matplotlib绘图时出现警告,我们可以尝试使用另一种支持中文的字体,比如“Microsoft YaHei”(微软雅黑),它在Windows系统中普遍存在。
修改设置:
```python
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei', 'KaiTi', 'SimSun'] # 尝试多种字体
```
这样,如果第一个字体不存在,会尝试下一个。
我们将在代码中做如下修改:
在`MedicalViewer`类之前,在模块的最开始设置matplotlib的字体。
由于代码中已经导入`matplotlib.pyplot as plt`,我们在导入后立即设置。
修改后的代码开头:
```python
import os
import sys
import numpy as np
import vtk
from vtk.util import numpy_support
import nibabel as nib # 用于读取NIfTI文件
from PyQt5.QtWidgets import (
QApplication, QMainWindow, QFileDialog,
QVBoxLayout, QHBoxLayout, QWidget,
QSlider, QLabel, QPushButton, QMessageBox, QProgressDialog
)
from PyQt5.QtCore import Qt, QThread, pyqtSignal
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei', 'KaiTi', 'SimSun'] # 尝试多种中文字体
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# ... 其他代码保持不变 ...
```
这样,在创建图形之前,字体设置已经生效。
另外,在`init_ui`方法中,我们创建了`FigureCanvas`,此时字体设置应该已经完成。
如果仍然出现警告,则可能是由于系统没有安装这些字体。在Linux系统中,可能需要安装中文字体包,如`fonts-wqy-microhei`或`fonts-wqy-zenhei`。
我们可以在代码中添加一个警告捕获,忽略这些字体缺失的警告,因为即使字体缺失,程序仍可运行(只是中文显示为方框)。
但是,我们更希望解决字体问题。因此,我们建议用户安装中文字体(如果程序运行在Linux上)。
总结:我们在代码开头设置matplotlib的字体为多个中文字体备选,并确保在创建图形前设置。
这样修改后,应该能解决大部分中文显示问题。
如果问题仍然存在,我们可以考虑使用以下方法:
1. 在代码中动态添加字体路径(如果有打包的字体文件)。
2. 使用`font_manager`的`FontProperties`为每个文本元素单独设置字体(比较繁琐)。
由于我们无法确定用户的环境,我们先采用上述设置多种备选字体的方法。
修改后的完整代码(仅修改开头部分)如下:
注意:由于我们增加了多个备选字体,并且设置了负号显示,应该能够避免大部分中文显示问题。
另外,在`MedicalViewer`类的`init_ui`方法中,我们创建了三个子图,并设置了标题(中文)。这些标题之前可能因为字体问题而出现警告,现在应该可以正常显示。
如果用户系统中没有上述任何一种字体,那么中文将无法显示,但程序不会崩溃,只是显示方框。此时,我们可以考虑在程序启动时检查中文字体是否存在,并给出提示。
但为了简化,我们暂时不做检查。
最后,我们修改代码并测试。
由于我们无法在用户环境中测试,只能尽量提供通用的解决方案。
现在,我们提供修改后的完整代码(仅修改了开头部分,其他部分不变)。
注意:由于代码很长,我们只修改了开头部分,其他部分保持不变。
完整代码修改如下(仅显示修改的开头部分,其余部分省略):</think># 解决 Matplotlib 中文字体缺失警告问题
在使用 Matplotlib 绘图时出现 `Glyph CJK UNIFIED IDEOGRAPH missing from font(s) DejaVu Sans` 警告,是因为 Matplotlib 默认使用的 DejaVu Sans 字体不支持中文字符。以下是完整的解决方案:
## 完整解决方案
```python
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.font_manager import FontProperties
# 解决方案1:使用系统支持的中文字体(推荐)
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'KaiTi', 'SimSun'] # 设置多个备选字体
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# 解决方案2:使用指定的字体文件路径(适用于自定义字体)
# 下载支持中文的字体文件(如Source Han Sans),然后指定路径
# font_path = '/path/to/your/font.ttf' # 替换为实际字体文件路径
# font_prop = FontProperties(fname=font_path)
# plt.rcParams['font.family'] = font_prop.get_name()
# 解决方案3:使用内置的字体管理器动态添加字体
# from matplotlib.font_manager import fontManager
# fontManager.addfont('/path/to/your/font.ttf') # 添加字体文件
# plt.rcParams['font.family'] = 'Your Font Name' # 使用添加的字体
# 测试绘图
plt.figure(figsize=(8, 4))
plt.plot([1, 2, 3, 4], [1, 4, 2, 3], label='测试曲线')
plt.title('中文标题示例')
plt.xlabel('X轴标签')
plt.ylabel('Y轴标签')
plt.legend(['图例说明'])
plt.grid(True)
plt.show()
```
## 解决方案详解
### 方法1:使用系统内置中文字体(推荐)
```python
import matplotlib.pyplot as plt
# 设置多个备选字体,按顺序尝试使用
plt.rcParams['font.sans-serif'] = [
'SimHei', # 黑体(Windows)
'Microsoft YaHei',# 微软雅黑(Windows)
'KaiTi', # 楷体(Windows)
'SimSun', # 宋体(Windows)
'STHeiti', # 华文黑体(macOS)
'STSong', # 华文宋体(macOS)
'WenQuanYi Micro Hei' # 文泉驿微米黑(Linux)
]
# 解决负号显示问题
plt.rcParams['axes.unicode_minus'] = False
```
### 方法2:使用自定义字体文件
1. **下载中文字体文件**:
- 推荐使用思源黑体(Source Han Sans)
- 下载地址:[GitHub - adobe-fonts/source-han-sans](https://github.com/adobe-fonts/source-han-sans)
2. **在代码中指定字体路径**:
```python
from matplotlib.font_manager import FontProperties
# 替换为你的字体文件实际路径
font_path = 'SourceHanSansSC-Regular.otf'
# 创建字体属性对象
font_prop = FontProperties(fname=font_path)
# 设置全局字体
plt.rcParams['font.family'] = font_prop.get_name()
```
### 方法3:动态添加字体到字体管理器
```python
import matplotlib.pyplot as plt
from matplotlib.font_manager import fontManager
# 添加字体文件到字体管理器
fontManager.addfont('SourceHanSansSC-Regular.otf') # 替换为你的字体文件
# 获取并设置字体名称
plt.rcParams['font.family'] = 'Source Han Sans SC'
```
## 常见问题排查
1. **字体名称不匹配**:
- 使用 `print(plt.rcParams['font.family'])` 查看当前使用的字体
- 使用 `from matplotlib.font_manager import fontManager; print(fontManager.ttflist)` 查看所有可用字体
2. **字体文件路径错误**:
- 使用绝对路径确保正确加载
- 检查文件权限
3. **字体缓存问题**:
- 删除 Matplotlib 缓存文件(通常位于 `~/.cache/matplotlib`)
- 重启 Python 内核或重新运行程序
4. **特殊环境问题(如 Jupyter Notebook)**:
```python
%matplotlib inline
import matplotlib as mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
```
## 完整示例代码
```python
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
# 设置中文字体解决方案
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'KaiTi', 'SimSun']
plt.rcParams['axes.unicode_minus'] = False
# 创建示例数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
# 创建图表
plt.figure(figsize=(10, 6), dpi=100)
# 绘制曲线
plt.plot(x, y1, label='正弦函数', color='royalblue', linewidth=2)
plt.plot(x, y2, label='余弦函数', color='crimson', linestyle='--', linewidth=2)
# 添加标题和标签
plt.title('三角函数可视化示例', fontsize=16, fontweight='bold')
plt.xlabel('X轴 - 角度(弧度)', fontsize=12)
plt.ylabel('Y轴 - 函数值', fontsize=12)
# 添加图例
plt.legend(loc='upper right', fontsize=10)
# 添加网格
plt.grid(True, linestyle='--', alpha=0.7)
# 设置坐标轴范围
plt.xlim(0, 10)
plt.ylim(-1.2, 1.2)
# 添加注释
plt.annotate('最大值点', xy=(np.pi/2, 1), xytext=(3, 0.8),
arrowprops=dict(facecolor='black', shrink=0.05))
# 显示图表
plt.tight_layout()
plt.show()
```
## 相关问题
1. **如何在 Docker 容器中解决 Matplotlib 中文显示问题?**
需要在 Dockerfile 中添加中文字体安装步骤:
```dockerfile
RUN apt-get update && apt-get install -y fonts-wqy-microhei
```
2. **如何批量处理 Matplotlib 图表的中文字符?**
可以在程序开始时一次性设置全局字体参数,避免在每个图表中重复设置[^1]。
3. **为什么在某些 Linux 系统中仍无法显示中文?**
可能需要安装额外字体包:`sudo apt install fonts-wqy-microhei fonts-wqy-zenhei`[^2]。
4. **如何导出包含中文的 PDF 文件?**
使用支持中文的字体(如 Source Han Sans)并设置:
```python
plt.savefig('output.pdf', bbox_inches='tight', dpi=300)
```
5. **如何在 Seaborn 中使用中文字体?**
Seaborn 基于 Matplotlib,设置方法相同:
```python
import seaborn as sns
sns.set(font='SimHei') # 设置Seaborn字体
```
[^1]: 在代码开头设置 `plt.rcParams` 可以确保所有后续图表都使用相同的中文字体设置。
[^2]: Linux 系统可能需要额外安装中文字体包才能正确显示中文。
阅读全文
相关推荐


















