You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用PIL/imageio获取网络国旗图片替换Matplotlib饼图文字标签

用国旗图片替换Matplotlib饼图的文字标签

Matplotlib的pie()方法不支持直接将图片作为标签,我们可以通过下载图片+在标签位置添加图片补丁的方式实现需求,以下是基于PIL/requests或imageio的完整解决方案:

依赖安装

如果使用PIL+requests:

pip install matplotlib pillow requests

如果使用imageio:

pip install matplotlib imageio

完整代码实现

方案1:使用PIL+requests加载网络图片

import matplotlib.pyplot as plt
from PIL import Image
import requests
from matplotlib.offsetbox import OffsetImage, AnnotationBbox

nationalities = {
    'Fr': 5,
    'De': 10,
    'It': 3,
    'Se': 5,
    'Pl':2,
    'Cz': 3,
}

flags = {
    'Fr':'https://www.touteleurope.eu/wp-content/uploads/2022/08/drapeau-France.png',
    'De':'https://www.touteleurope.eu/wp-content/uploads/2022/07/drapeau-allemagne.png',
    'It':'https://www.touteleurope.eu/wp-content/uploads/2022/08/drapeau-Italie.png',
    'Se':'https://www.touteleurope.eu/wp-content/uploads/2022/07/1280px-Flag_of_Sweden.svg.png',
    'Pl':'https://www.touteleurope.eu/wp-content/uploads/2022/08/drapeau-Pologne.png',
    'Cz':'https://www.touteleurope.eu/wp-content/uploads/2022/08/drapeau-Republique-tcheque.png',
}

# 从URL加载国旗图片
def load_flag(url):
    response = requests.get(url, stream=True)
    return Image.open(response.raw)

fig, ax = plt.subplots(figsize=(18,6))
plt.xticks(fontsize=20)
plt.yticks([], fontsize=20)

composer_counts = list(nationalities.values())
country_codes = list(nationalities.keys())

# 绘制饼图,用空字符串占位标签,获取每个标签的位置对象
wedges, texts = plt.pie(
    composer_counts,
    labels=['']*len(composer_counts),
    radius=1,
    wedgeprops={'linewidth': 1.0, 'edgecolor': 'white'},
)

# 计算最大占比的百分比
max_percent = 100 * max(composer_counts) / sum(composer_counts)
print(f"{int(max_percent)}%")

# 为每个标签位置添加国旗图片
for text, code in zip(texts, country_codes):
    # 获取原文字标签的坐标
    x, y = text.get_position()
    # 加载并调整图片大小
    flag_img = load_flag(flags[code])
    img_box = OffsetImage(flag_img, zoom=0.1)  # zoom参数控制图片缩放比例
    # 将图片绑定到坐标位置,关闭边框
    ab = AnnotationBbox(img_box, (x, y), frameon=False)
    ax.add_artist(ab)

# 添加中心百分比文本
plt.text(s=f"{int(max_percent)}%", x=-0.7, y=0.3, fontsize=30, color='white')
plt.tight_layout()
plt.show()

方案2:使用imageio加载网络图片

仅需替换图片加载函数,其余代码与方案1一致:

import imageio.v3 as iio

# 从URL加载国旗图片
def load_flag(url):
    return iio.imread(url)

关键步骤说明

  1. 图片加载:通过requests/imageio从网络获取图片,PIL/imageio负责图片格式处理
  2. 饼图绘制:用空字符串占位标签,获取texts对象以获取每个标签的坐标位置
  3. 图片嵌入:使用OffsetImage将图片转为Matplotlib兼容对象,AnnotationBbox将图片绑定到对应坐标,zoom参数可调整图片大小适配饼图

内容的提问来源于stack exchange,提问作者RémyClaverie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 01:05:20