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

PyScript中Matplotlib图表及刻度显示异常,Pydroid运行正常求助

问题排查与解决

核心问题分析

  1. 绘图状态未重置:每次调用run函数时,Matplotlib的全局绘图对象没有被重置,新图表会叠加在旧图表上,导致显示混乱。
  2. 数据类型错误:通过Element().value获取的输入框值是字符串类型,直接存入numpy数组后,X轴会被识别为类别型数据而非数值型,引发刻度显示异常。
  3. PyScript环境适配问题:Matplotlib在PyScript中的默认后端渲染逻辑与本地Python环境(如Pydroid)不同,直接输出全局绘图对象会导致渲染异常。

修复后的完整代码

Python逻辑部分

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_agg import FigureCanvasAgg

def run(*args, **kwargs):
    # 重置所有旧绘图,创建新画布和轴对象
    plt.close('all')
    fig, ax = plt.subplots()

    # 封装输入值转换函数,处理字符串转数值
    def get_numeric_value(element_id):
        raw_val = Element(element_id).value
        try:
            return float(raw_val) if '.' in raw_val else int(raw_val)
        except ValueError:
            return 0  # 兜底处理无效输入

    # 获取并转换所有输入数据
    x_data = [get_numeric_value(f"te{i}") for i in range(1,6)]
    y_data = [get_numeric_value(f"te{i}") for i in range(6,11)]
    
    title = Element("title").value
    x_label = Element("xl").value 
    y_label = Element("yl").value 

    # 设置图表基础属性
    ax.set_title(title)
    ax.set_xlabel(x_label)
    ax.set_ylabel(y_label)

    x = np.array(x_data)
    y = np.array(y_data)
    bar_colors = ["darkorange", "deeppink", "#04aa6d", "orchid", "dodgerblue"]

    # 根据选择绘制对应图表
    chart_type = Element("selection").value
    if chart_type == "line" or chart_type == "":
        ax.plot(x, y)
    elif chart_type == "scatter":
        ax.scatter(x, y)
    elif chart_type == "barg":
        ax.bar(x, y, color=bar_colors)
    elif chart_type == "pie":
        # 饼图单独处理,清除原有轴并创建新子图
        fig.clear()
        ax = fig.add_subplot()
        ax.pie(y, labels=x)
        ax.legend()

    # 渲染图像为RGBA数组,适配PyScript页面输出
    canvas = FigureCanvasAgg(fig)
    canvas.draw()
    img_array = np.asarray(canvas.buffer_rgba())
    pyscript.write("res", img_array)

HTML完整结构

<!-- 图表类型选择下拉框 -->
<select id="selection">
    <option value="" selected disabled>Select ( Graph / Chart ) Type</option>
    <option value="line">Line Graph</option>
    <option value="scatter">Scattered Graph</option>
    <option value="barg">Bar Graph</option>
    <option value="pie">Pie Chart</option>
</select>

<!-- X轴数据输入区 -->
<div id="table1">
    <input type="number" id="te1" placeholder="enter a no." value="1">
    <input type="number" id="te2" placeholder="enter a no." value="2">
    <input type="number" id="te3" placeholder="enter a no." value="3">
    <input type="number" id="te4" placeholder="enter a no." value="4">
    <input type="number" id="te5" placeholder="enter a no." value="5">
</div>

<!-- Y轴数据输入区 -->
<div>
    <input type="number" id="te6" placeholder="enter a no." value="48">
    <input type="number" id="te7" placeholder="enter a no." value="53">
    <input type="number" id="te8" placeholder="enter a no." value="60">
    <input type="number" id="te9" placeholder="enter a no." value="68">
    <input type="number" id="te10" placeholder="enter a no." value="72">
</div>

<!-- 图表标题与轴标签输入 -->
<input type="text" id="title" placeholder="Enter chart title" value="Sample Chart">
<input type="text" id="xl" placeholder="X-axis label" value="X Values">
<input type="text" id="yl" placeholder="Y-axis label" value="Y Values">

<!-- 提交按钮 -->
<button id="sub" pys-onClick="run">Submit</button>

<!-- 图表输出容器 -->
<div id="res"></div>

关键修复点说明

  • 重置绘图状态:每次调用run时执行plt.close('all')清除旧画布,创建新的fig和ax对象,彻底避免图表叠加问题。
  • 数据类型转换:新增get_numeric_value函数将输入的字符串值转为数值类型,确保numpy数组存储的是数值而非字符串,解决X轴刻度显示异常。
  • 适配PyScript渲染:使用FigureCanvasAgg将Matplotlib画布渲染为RGBA数组,再通过pyscript.write输出到页面,解决浏览器环境下的渲染适配问题。
  • 饼图特殊处理:清除原有轴对象并重新创建子图,避免饼图与常规轴布局冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 19:33:32