不使用kivy-garden工具在Kivy中显示Matplotlib绘图的方法问询
Kivy嵌入绘图(无kivy-garden+后端无关方案)
以下是完全脱离kivy-garden依赖,支持Matplotlib、Plotly及原生OpenGL图形嵌入的具体实现:
一、Matplotlib嵌入(无kivy-garden)
核心思路是将Matplotlib绘图渲染为内存中的图像字节流,直接传入Kivy的Image组件,无需依赖garden专用组件。
完整代码
import kivy from kivy.app import App from kivy.uix.image import Image from kivy.graphics.texture import Texture import matplotlib.pyplot as plt from io import BytesIO class MatplotlibEmbedApp(App): def build(self): # 绘制Matplotlib图形 fig, ax = plt.subplots(figsize=(4,3)) ax.plot([1,2,3,4], [1,4,9,16]) ax.set_title("Matplotlib (No Garden)") # 导出为PNG字节流(替代plt.show()) buf = BytesIO() fig.savefig(buf, format='png', dpi=100) buf.seek(0) # 转为Kivy纹理并修正坐标系 texture = Texture.create_from_bytes(buf.read()) texture.flip_vertical() # 解决Matplotlib与Kivy的Y轴方向差异 img = Image(texture=texture) plt.close(fig) # 释放Matplotlib资源 return img if __name__ == "__main__": MatplotlibEmbedApp().run()
关键细节
- 用
BytesIO避免磁盘IO,全程内存处理图像 - 必须执行
flip_vertical(),否则图像会倒置 - 手动关闭
fig防止内存泄漏
二、Plotly嵌入Kivy
Plotly同样通过导出图像字节流的方式嵌入,核心逻辑与Matplotlib一致,仅导出方式不同。
前置依赖
需要安装Plotly及轻量渲染器:
pip install plotly kaleido
完整代码
import kivy from kivy.app import App from kivy.uix.image import Image from kivy.graphics.texture import Texture import plotly.express as px from io import BytesIO class PlotlyEmbedApp(App): def build(self): # 绘制Plotly散点图 df = px.data.iris() fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species") # 导出为PNG字节流 buf = BytesIO() fig.write_image(buf, format='png', width=400, height=300) buf.seek(0) # 转为Kivy纹理并显示 texture = Texture.create_from_bytes(buf.read()) texture.flip_vertical() img = Image(texture=texture) return img if __name__ == "__main__": PlotlyEmbedApp().run()
关键细节
kaleido是Plotly官方推荐的轻量图像渲染器,替代旧版orca- 通过
width/height参数控制输出尺寸,匹配Kivy组件大小
三、原生OpenGL图形嵌入
Kivy底层基于OpenGL,直接通过自定义Widget即可实现原生OpenGL渲染,无需额外依赖。
完整代码(基础三角形示例)
import kivy from kivy.app import App from kivy.uix.widget import Widget from kivy.graphics import Color, Triangle, PushMatrix, PopMatrix, Translate class OpenGLWidget(Widget): def __init__(self, **kwargs): super().__init__(**kwargs) with self.canvas: # 绘制红色居中三角形(Kivy封装的OpenGL接口) Color(1, 0, 0, 1) PushMatrix() Translate(self.center_x, self.center_y, 0) Triangle(points=[-100, -100, 100, -100, 0, 100]) PopMatrix() class OpenGLApp(App): def build(self): return OpenGLWidget() if __name__ == "__main__": OpenGLApp().run()
进阶说明
若需更底层的OpenGL操作(如直接调用glBegin/glVertex),可重写Widget的on_draw方法,Kivy会自动管理OpenGL上下文。
后端无关性总结
所有方案的核心逻辑统一,实现完全的绘图后端无关:
- 用目标绘图库生成图形
- 将图形导出为标准图像字节流(PNG/JPG等)
- 用Kivy的
Texture.create_from_bytes转为纹理 - 用
Image组件显示
替换绘图库仅需修改前两步代码,Kivy的显示逻辑无需改动。
内容的提问来源于stack exchange,提问作者krishnab
相关产品推荐
相关产品推荐

