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

不使用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上下文。

后端无关性总结

所有方案的核心逻辑统一,实现完全的绘图后端无关:

  1. 用目标绘图库生成图形
  2. 将图形导出为标准图像字节流(PNG/JPG等)
  3. 用Kivy的Texture.create_from_bytes转为纹理
  4. 用Image组件显示

替换绘图库仅需修改前两步代码,Kivy的显示逻辑无需改动。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 05:51:29