【问题标题】:how to display matplotlib charts in tkinter如何在 tkinter 中显示 matplotlib 图表
【发布时间】:2023-03-06 11:59:01
【问题描述】:

我试图在 tkinter 窗口中显示 4 个或更多图表,但它们放错了位置,我认为我也需要一个滚动条。这是代码:

root = tk.Tk()

    figure1 = plt.Figure(figsize=(2,2), dpi=100)

    ax1 = figure1.add_subplot(221)
    ax1.plot(df1['year'], df1['personal'], color='red')
    scatter1 = FigureCanvasTkAgg(figure1, root)
    scatter1.get_tk_widget().pack()
    ax1.legend([''])
    ax1.set_xlabel('valeur de personals')
    ax1.set_title('ev de personal ')

    figure2 = plt.Figure(figsize=(2,2), dpi=100)
    ax2 = figure2.add_subplot(222)
    scatter2 = FigureCanvasTkAgg(figure2, root)
    scatter2.get_tk_widget().pack(side=tk.RIGHT)
    ax2.legend([''])
    ax2.set_xlabel('valeur BSA')
    ax2.set_title('Evolutiion des valeurs BSA depuis 1990 ')
    ax2.plot(df2['year'], df2['value'], color='red')

    figure3 = plt.Figure(figsize=(2,2), dpi=100)
    ax3 = figure3.add_subplot(223)
    #the same code for the reste 


    root.mainloop()

但这是结果:

【问题讨论】:

  • 如果你把地块放在分开的FigureCanvasTkAgg 中,那么你就不需要subplot(221) (等等),因为它在每个FigureCanvasTkAgg 中创建了4个地块的位置,但你只使用每个FigureCanvasTkAgg 中的一个位置。如果你想使用subplot(221),那么你只需要一个FigureCanvasTkAgg
  • @furas 但 FigureCanvasTkAgg 没有属性 'plot' to plot(df1['year'], df1['personal'], color='red')
  • 使用普通的plot,但不要为每个新地块创建新的figure和新的FigureCanvasTkAgg

标签: python matplotlib tkinter


【解决方案1】:

我发现了两个问题

第一:

您创建 4 个画布 FigureCanvasTkAgg 并在每个画布上使用 add_subplot(222) 为 4 个绘图 (2x2) 创建位置,但您在每个画布中只使用一个位置。为此,您只能使用一个画布。

第二:

您需要pack(fill="both", expand=True) 来调整绘图大小并使用窗口中的所有空间。

您还使用pack(side=tk.RIGHT),这可能会导致布局出现问题


最少的工作代码

import tkinter as tk
import pandas as pd
import matplotlib.pyplot as plt

import matplotlib
matplotlib.use("TkAgg")

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
#from matplotlib.figure import Figure

df1 = pd.DataFrame({
    'year': [2001, 2002, 2003],
    'value': [1, 3, 2],
    'personal': [9, 1, 5],
})

df2 = pd.DataFrame({
    'year': [2001, 2002, 2003],
    'value': [1, 3, 2],
    'personal': [9, 1, 5],
})

# --- 

root = tk.Tk()

figure = plt.Figure(figsize=(2,2), dpi=100)

scatter = FigureCanvasTkAgg(figure, root)
scatter.get_tk_widget().pack() #fill='both', expand=True)

# --- 

ax1 = figure.add_subplot(221)
ax1.plot(df1['year'], df1['personal'], color='red')

ax1.legend([''])
ax1.set_xlabel('valeur de personals')
ax1.set_title('ev de personal ')

# --- 

ax2 = figure.add_subplot(222)
ax2.plot(df2['year'], df2['value'], color='red')

ax2.legend([''])
ax2.set_xlabel('valeur BSA')
ax2.set_title('Evolutiion des valeurs BSA depuis 1990 ')

# --- 

ax3 = figure.add_subplot(223)
ax3.plot(df1['year'], df1['personal'], color='red')

ax3.legend([''])
ax3.set_xlabel('valeur de personals')
ax3.set_title('ev de personal ')

# --- 

ax4 = figure.add_subplot(224)
ax4.plot(df2['year'], df2['value'], color='red')

ax4.legend([''])
ax4.set_xlabel('valeur BSA')
ax4.set_title('Evolutiion des valeurs BSA depuis 1990 ')

# ---

root.mainloop()

结果:


编辑:

与 4 个画布相同 - 每个画布仅使用 add_plot('111') 保留一个绘图 - 但这次我使用 grid() 而不是 pack() 来组织它。

它需要columnconfigurerowconfigure 来调整单元格大小并使用窗口中的所有空间。和grid( ..., sticky='news') 将画布调整为单元格的大小。

import tkinter as tk
import pandas as pd
import matplotlib.pyplot as plt

import matplotlib
matplotlib.use("TkAgg")

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
#from matplotlib.figure import Figure

df1 = pd.DataFrame({
    'year': [2001, 2002, 2003],
    'value': [1, 3, 2],
    'personal': [9, 1, 5],
})

df2 = pd.DataFrame({
    'year': [2001, 2002, 2003],
    'value': [1, 3, 2],
    'personal': [9, 1, 5],
})

# --- 

root = tk.Tk()

# resize grid
root.columnconfigure(0, weight=1)
root.columnconfigure(1, weight=1)
root.rowconfigure(0, weight=1)
root.rowconfigure(1, weight=1)

# --- 

figure1 = plt.Figure(figsize=(2,2), dpi=100)

scatter1 = FigureCanvasTkAgg(figure1, root)
scatter1.get_tk_widget().grid(row=0, column=0, sticky='news')
#scatter1.get_tk_widget().pack(fill='both', expand=True)

ax1 = figure1.add_subplot(111)
ax1.plot(df1['year'], df1['personal'], color='red')

ax1.legend([''])
ax1.set_xlabel('valeur de personals')
ax1.set_title('ev de personal ')

# --- 

figure2 = plt.Figure(figsize=(2,2), dpi=100)

scatter2 = FigureCanvasTkAgg(figure2, root)
scatter2.get_tk_widget().grid(row=0, column=1, sticky='news')
#scatter2.get_tk_widget().pack(side='right', fill='both', expand=True)

ax2 = figure2.add_subplot(111)
ax2.plot(df2['year'], df2['value'], color='red')

ax2.legend([''])
ax2.set_xlabel('valeur BSA')
ax2.set_title('Evolutiion des valeurs BSA depuis 1990 ')

# --- 

figure3 = plt.Figure(figsize=(2,2), dpi=100)

scatter3 = FigureCanvasTkAgg(figure3, root)
scatter3.get_tk_widget().grid(row=1, column=0, sticky='news')
#scatter3.get_tk_widget().pack(fill='both', expand=True)

ax3 = figure3.add_subplot(111)
ax3.plot(df1['year'], df1['personal'], color='red')

ax3.legend([''])
ax3.set_xlabel('valeur de personals')
ax3.set_title('ev de personal ')

# --- 

figure4 = plt.Figure(figsize=(2,2), dpi=100)

scatter4 = FigureCanvasTkAgg(figure4, root)
scatter4.get_tk_widget().grid(row=1, column=1, sticky='news')
#scatter4.get_tk_widget().pack(fill='both', expand=True)

ax4 = figure4.add_subplot(111)
ax4.plot(df2['year'], df2['value'], color='red')

ax4.legend([''])
ax4.set_xlabel('valeur BSA')
ax4.set_title('Evolutiion des valeurs BSA depuis 1990 ')

# ---

root.mainloop()

结果:

现在地块的边距变小了。

【讨论】:

  • 我添加了使用 4 个画布的示例,但这次我使用 grid() 而不是 pack() 将画布放在 2 行和 2 列中。
  • 我想添加一个滚动条,但我找到的所有教程都使用框架
  • tkinter 可以使用带有小部件 TextLIstboxCanvas 的滚动条,滚动其他元素的唯一方法是将小部件放在 Canvas 上并滚动此 Canvas。您可以使用滚动条将Frame 放在Canvas 上(以构建“滚动框架”),然后将绘图放在Frame 中,就像在How to add a scrollbar to window made with tkinter 中一样。
  • 我在 Guthub 上将 ScrolledFrame 的代码保存在 python-examples -> Scrolled Frame and Canvas,但也有人创建了模块 tkScrolledFrame
猜你喜欢
  • 2020-06-19
  • 1970-01-01
  • 2015-10-11
  • 2018-03-02
  • 1970-01-01
  • 2021-11-18
  • 1970-01-01
  • 2021-10-02
  • 2023-03-24
相关资源
最近更新 更多