Python matplotlib 如何**同时**展示正文和 emoji

267 阅读3分钟

image.png

图片来自参考文档

我们可以支持中文展示或者 emoji 展示但是同时支持目前还没看到互联网有文章说明,故记录之。

TLDR:

plt.rc("font", family="YouYuan, Segoe UI Emoji")

plt.rcParams["font.family"] = "Segoe UI Emoji, YouYuan"

重点是将支持中文和 emoji 的 font-family 用, 分隔,顺序不要紧,这样如果遇到中文就使用中文字体,如果遇到不认识的 emoji 就回退到 emoji 支持的字体。

如果改成

plt.rcParams["font.sans-serif"].insert(0, "YouYuan")
plt.rcParams["font.sans-serif"].insert(0, "Segoe UI Emoji")

则只能支持中文或 emoji一种,因为仅会使用数组第一项。

试一试

image.png

import numpy as np
import matplotlib.pyplot as plt


plt.rc("font", family="YouYuan, Segoe UI Emoji")
# plt.rcParams["font.family"] = "Segoe UI Emoji, YouYuan"

data = np.random.randint(100, 500, 7)
labels = [
    "🍎 苹果",
    "🍌 香蕉",
    "🍑 桃子",
    "🍒 樱桃",
    "🍇 葡萄",
    "🥭 芒果",
    "🍍 菠萝",
]

plt.figure(figsize=[5, 5], dpi=120)

plt.pie(
    data,
    autopct="%.1f%%",
    radius=1,
    pctdistance=0.8,
    colors=np.random.rand(7, 3),
    # explode=[0.05, 0, 0.1, 0, 0, 0, 0],
    # shadow=True,
    textprops=dict(fontsize=8, color="black"),
    wedgeprops=dict(linewidth=1, width=0.35),
    labels=labels,
)

plt.title("水果销售占比")
plt.show()

代码来自 Python-100-Days/Day66-80/78.数据可视化-1.md,稍加修改。

matplotlib 设置字体的三种方式

临时修改 rcParamsrc 方法

rcParams 里面是 matplotlib 运行时的所有配置。

import matplotlib.pyplot as plt
import numpy as np

# Set the font family to support Chinese
+ plt.rcParams['font.family'] = 'SimHei'
+ # plt.rc("font", family="SimHei")

# Generate some data
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)

plt.plot(x, y)
plt.title('正弦函数')
plt.xlabel('角度 (弧度)')
plt.ylabel('正弦值')
plt.show()

一次性解决 matplotlibrc

import matplotlib
print(matplotlib.get_configdir())

拿到目录如果没有 matplotlibrc 则新建一个配置文件,增加:

font.family         : SimHei

设置不在范围内的字体文件 matplotlib.font_manager.FontProperties

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.font_manager import FontProperties

# Generate some data
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)

# Load a specific font
font_path = 'path/to/your/font.ttf'
font_prop = FontProperties(fname=font_path)

plt.plot(x, y)
plt.title('正弦函数', fontproperties=font_prop)
plt.xlabel('角度 (弧度)', fontproperties=font_prop)
plt.ylabel('正弦值', fontproperties=font_prop)
plt.show()

除了 YouYuan 还有哪些中文字体

除了常见的 Microsoft Yahei Microsoft JhengHei SimHei,还有哪些?

查询当前系统所有字体

# font.py
from matplotlib.font_manager import FontManager


mpl_fonts = set(f.name for f in FontManager().ttflist)

print(f"all font list get from matplotlib.font_manager ({len(mpl_fonts)}):")
for f in sorted(mpl_fonts):
    print("  ", f)

print("字体数量:", len(mpl_fonts))

如果发现有些是中文拼音的就可以,比如 YouYuan

DengXian
FangSong
FZShouJinShu-S10S # 宋徽宗瘦金体
KaiTi
LiSu
Microsoft JhengHei
Microsoft YaHei
YouYuan

除了 Segoe UI Emoji 还有哪些 emoji 字体

❯ uv run font.py | grep emoji -i
Segoe UI Emoji

目前我的系统仅有一枚,即 Segoe UI Emoji

其他解决方案

中文解决方案

这个库可以 Zh-Plot: 一行代码搞定 Python 图表中文展示,使用很简单,为什么很简单,其实就是在 install 这个库的时候源文件里面已经包含了支持中文的字体文件。

+ import zhplot
import matplotlib.pyplot as plt

我的看法这个解法太重了,一个字体文件 10M,故还是使用系统自带中文字体比较合适。

image.png

github.com/shenxiangzh…

emoji 解决方案

pypi.org/project/imo… 没尝试。

我们的简单方案有存在一个小问题,颜色没有丰富多样。下面这个貌似能解决颜色的问题,nfraprado.net/post/using-… 使用 github.com/matplotlib/… 感兴趣可以试试。

matplotlib.use("module://mplcairo.gtk")

image.png

更多阅读

参考