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

如何在Tkinter中显示Matplotlib 3D绘图并保留Canvas背景色

问题描述

我有一段生成3D曲面图的Matplotlib代码:

import numpy as np
import matplotlib.pyplot as plt

# 创建figure对象
surf_3D = plt.figure()

# 创建3D坐标轴对象
axes_3d = plt.axes(projection = "3d")

# 生成X和Y数据
x_demo3d = np.arange(-5,5,0.1)
y_demo3d = np.arange(-5,5,0.1)

# 创建网格数据
X3,Y3 = np.meshgrid(x_demo3d, y_demo3d)

# 生成Z数据(正弦余弦组合)
Z3 = np.sin(X3) * np.cos(Y3)

# 绘制3D曲面
axes_3d.plot_surface(X3, Y3, Z3, cmap = "plasma")

# 设置坐标轴面板透明
axes_3d.xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
axes_3d.yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
axes_3d.zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))

# 隐藏坐标轴刻度
axes_3d.set_xticks([])
axes_3d.set_yticks([])
axes_3d.set_zticks([])

# 显示图形
surf_3D.show()

这段代码能生成正常的3D曲面图。

之后我尝试把这个3D绘图嵌入到Tkinter窗口的深红色背景Canvas中,代码如下:

import numpy as np
import matplotlib.pyplot as plt
from tkinter import *
from matplotlib.backends.backend_tkagg import (
     FigureCanvasTkAgg, NavigationToolbar2Tk)


class Program_Class:
    
    def __init__(self, master):

        # 主窗口参数设置
        Main.resizable(0,0)
        Main.geometry("900x550")
        Main.title("Main")

        # 创建figure对象
        surf_3D = plt.figure(figsize=(2,2))

        # 创建3D坐标轴对象
        axes_3d = plt.axes(projection = "3d")

        # 生成X和Y数据
        x = np.arange(-5,5,0.1)
        y = np.arange(-5,5,0.1)

        # 创建网格数据
        x, y = np.meshgrid(x, y)

        # 生成Z数据(正弦余弦组合)
        z = np.sin(x) * np.cos(y)

        # 绘制3D曲面
        axes_3d.plot_surface(x, y, z, cmap = "plasma")

        # 设置坐标轴面板透明
        axes_3d.xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
        axes_3d.yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
        axes_3d.zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))

        # 隐藏坐标轴刻度
        axes_3d.set_xticks([])
        axes_3d.set_yticks([])
        axes_3d.set_zticks([])

        # 尝试将绘图嵌入Canvas(背景色设为深红色#8B0000)
        Canvas_demo3d = Canvas(Main, width=300, height =200, borderwidth=0, highlightthickness=0, 
                                    bg='#8B0000')
        Canvas_demo3d = FigureCanvasTkAgg(surf_3D, master=Main)
        Canvas_demo3d.get_tk_widget().place(x=300,y=71)
        Canvas_demo3d.draw()


Main = Tk()
Program_Class(Main)
Main.mainloop()

实际运行后发现,绘图占据了Canvas的全部空间,看不到设置的深红色背景。请问如何修改代码,让未被绘图覆盖的Canvas区域显示自定义背景色,同时正常展示3D曲面图?


解决方案

问题根源是你创建Tkinter Canvas后,用FigureCanvasTkAgg对象覆盖了它的变量引用,且Matplotlib的figure默认白色背景会挡住下方Canvas。修改步骤如下:

  1. 保留Tkinter Canvas作为底层背景,不覆盖变量
  2. 设置Matplotlib的figure和坐标轴背景为透明,让底层Canvas颜色透出
  3. 将Matplotlib绘图控件放置在背景Canvas上方

修改后的完整代码:

import numpy as np
import matplotlib.pyplot as plt
from tkinter import *
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg


class Program_Class:
    def __init__(self, master):
        # 主窗口参数设置
        master.resizable(0,0)
        master.geometry("900x550")
        master.title("Main")

        # 1. 创建深红色背景的Canvas作为底层
        canvas_bg = Canvas(master, width=300, height=200, borderwidth=0, 
                           highlightthickness=0, bg='#8B0000')
        canvas_bg.place(x=300, y=71)

        # 2. 创建Matplotlib figure并设置背景透明
        surf_3D = plt.figure(figsize=(2,2), facecolor='none')
        # 创建3D坐标轴并设置背景透明
        axes_3d = plt.axes(projection="3d", facecolor='none')

        # 生成数据和绘制曲面
        x = np.arange(-5,5,0.1)
        y = np.arange(-5,5,0.1)
        x, y = np.meshgrid(x, y)
        z = np.sin(x) * np.cos(y)
        axes_3d.plot_surface(x, y, z, cmap="plasma")

        # 设置坐标轴面板透明
        axes_3d.xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
        axes_3d.yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
        axes_3d.zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))

        # 隐藏坐标轴刻度
        axes_3d.set_xticks([])
        axes_3d.set_yticks([])
        axes_3d.set_zticks([])

        # 3. 创建Matplotlib画布并绑定到背景Canvas,放置在上方
        canvas_plot = FigureCanvasTkAgg(surf_3D, master=canvas_bg)
        canvas_plot.get_tk_widget().pack(fill=BOTH, expand=True)
        canvas_plot.draw()


Main = Tk()
Program_Class(Main)
Main.mainloop()

关键修改说明:

  • 拆分变量:将原Canvas_demo3d拆分为canvas_bg(底层背景)和canvas_plot(Matplotlib绘图控件),避免变量覆盖
  • 透明设置:创建plt.figure时添加facecolor='none',创建3D坐标轴时添加facecolor='none',让底层背景透出
  • 层级绑定:把Matplotlib绘图控件绑定到背景Canvas上,通过pack适配Canvas大小,确保绘图区域外显示深红色背景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 08:51:05