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

执行plt.subplots()时偶发Fail to create pixmap错误求解决

解决Matplotlib创建图时的Fail to create pixmap偶发错误

错误原因

这个错误源于Matplotlib默认使用的TkAgg后端(依赖Tkinter),它在资源释放不及时或并发调用场景下容易出现pixmap创建失败的问题——Tk后端并非线程安全,且频繁创建/销毁Figure时可能残留未释放的UI资源,导致偶发的资源分配失败。

解决方案

1. 切换到无UI后端(推荐)

将Matplotlib的后端切换为非交互式的Agg后端,彻底避开Tk相关的UI资源问题。在导入matplotlib.pyplot后添加以下设置:

import matplotlib.pyplot as plt
plt.switch_backend('Agg')  # 切换到无UI的Agg后端

2. 确保资源彻底清理

虽然plt.close(fig)会关闭当前Figure,但可以额外调用plt.close('all')确保所有资源完全释放:

# 在关闭单个fig后添加
plt.close('all')

3. 避免并发调用(如果存在)

如果函数被多线程/多进程调用,需要确保Matplotlib的操作在单线程环境执行,或给相关代码加线程锁:

import threading
lock = threading.Lock()

def getCurrentBatterySOCImage(batterySOC):
    with lock:
        # 原函数中Matplotlib相关的代码块
        red = Color("red")
        colors = list(red.range_to(Color("#23b818"), 101))
        color = colors[round(batterySOC)].hex
        fig, ax = plt.subplots(facecolor="black")
        # ... 其余Matplotlib操作代码
        plt.close(fig)
    # 后续PIL和文件操作代码可放在锁外

修改后的完整代码示例

from bs4 import BeautifulSoup
from PIL import ImageDraw, Image, ImageFont
from colour import Color
import base64
from io import BytesIO
import matplotlib.pyplot as plt

# 切换到Agg后端,避免Tk相关资源问题
plt.switch_backend('Agg')

def getCurrentBatterySOCImage(batterySOC):
   red = Color("red")
   colors = list(red.range_to(Color("#23b818"), 101))
   color = colors[round(batterySOC)].hex
   fig, ax = plt.subplots(facecolor="black")
   ax.set_facecolor("black")
   fig.tight_layout()
   ax.axis("off")
   ax.bar([1], batterySOC, color=color)
   ax.axis([0.6,1.4,0,100])
   ax.set_aspect(.02)

   tmpfile = BytesIO()
   fig.savefig(tmpfile, format="png", pad_inches=0, bbox_inches="tight")
   plt.close(fig)
   plt.close('all')  # 彻底清理所有Matplotlib资源

   bar = Image.open(tmpfile)
   bar = bar.resize((107, 208))
   img = Image.new("RGBA", (136, 248), (255, 0, 0, 0))
   img.paste(bar, (14, 26), bar)
   battery = Image.open("img/battery.png")

   img.paste(battery, (0, 0), battery)


   font = ImageFont.truetype('font/RobotoMono.ttf', 40)
   message = f"{batterySOC}%"

   draw = ImageDraw.Draw(img)
   w, h = draw.textsize(message, font=font)

   draw.text(((136-w)/2, (248-h)/2), f"{batterySOC}%", fill=(255, 255, 255), font=font, stroke_width=2, stroke_fill="black")

   tmpfile1 = BytesIO()
   img.save(tmpfile1, format="png")
   encoded = base64.b64encode(tmpfile1.getvalue()).decode('utf-8')

   with open("index.html") as fp:
       soup = BeautifulSoup(fp, "html.parser")
       soup.find("img", attrs={'id': 'battery'})['src'] = f"data:image/png;base64,{encoded}"
   with open("index.html", "w") as fp:
       fp.write(soup.decode())
   return

内容的提问来源于stack exchange,提问作者monkaCode

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 09:55:24