Не отображается график matplotlib в окне tkinter
Пустой экран при вводе данных в программу. Пока не добавил окно matplotlib в tkinter все работало. Может это из-за графика зависит.

import matplotlib.pyplot as plt
import matplotlib
import numpy as np
import tkinter as tk
from matplotlib.figure import Figure
from matplotlib.colors import LinearSegmentedColormap
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
win = tk.Tk()
win.geometry ('900x900+600+300')
def draw_graph():
x, y, z, X, Y, mask = makeData()
global canvas1
if canvas1:
canvas1.get_tk_widget().destroy()
fig = Figure(figsize=(10, 6), dpi=100)
canvas1 = FigureCanvasTkAgg(fig, master = win)
canvas1.draw()
axes = plt.axes(projection="3d")
cmap = LinearSegmentedColormap.from_list('red_blue', ['b', 'g', 'y', 'r'], 256)
axes.scatter(x, y, z *(1 + mask * 0.75), c=z *(1 + mask * 0.75), cmap=cmap)
toolbar = NavigationToolbar2Tk(canvas1, win)
toolbar.update()
canvas1.get_tk_widget().pack(side=tk.TOP, fill=tk.NONE, expand=0)
win.after(200, None)
def makeData():
a=int(q.get()) #19
b=float(w.get()) #20
c=int(e.get()) #200
x0=float(t.get()) #19.3
y0=float(u.get()) #19.6
r=float(i.get()) #.1
x = np.linspace(a, b, c) # создаем массив из 100 чисел float от 19 до 20 с равномернов шагом
y = np.linspace(a, b, c)
xgrid, ygrid = np.meshgrid(x, y)
z = np.random.normal(xgrid, ygrid)
r = .1 # радиус маски
X, Y = np.meshgrid(x, y)
mask = (X - x0) ** 2 + (Y - y0) ** 2 < r ** 2
return xgrid, ygrid, z, X, Y, mask
canvas1 = None
tk.Label(win, text='Введите начало массива a = ').pack(padx = 5, pady = 5)
tk.Label(win, text='Введите конец массива b = ').pack(padx = 5, pady = 5)
tk.Label(win, text='Введите количество точек массива: ').pack(padx = 5, pady = 5)
tk.Label(win, text='Центр маски по x от a = ').pack(padx = 5, pady = 5)
tk.Label(win, text='Центр маски по y до b = ').pack(padx = 5, pady = 5)
tk.Label(win, text='Радиус маски r = ').pack(padx = 5, pady = 5)
q = tk.Entry()
w = tk.Entry()
e = tk.Entry()
t = tk.Entry()
u = tk.Entry()
i = tk.Entry()
q.pack(padx = 5, pady = 5)
w.pack(padx = 5, pady = 5)
e.pack(padx = 5, pady = 5)
t.pack(padx = 5, pady = 5)
u.pack(padx = 5, pady = 5)
i.pack(padx = 5, pady = 5)
tk.Button(win, text='Ввести точки', command=draw_graph).pack(padx = 5, pady = 5)
win.mainloop()
Ответы (2 шт):
Автор решения: Костя Килиманов
→ Ссылка
Для более удобного вида программы лучше применить позиционирование .grid(column,row)
tk.Label(win, text='Введите начало массива a = ').grid(column=1,row=1)
tk.Label(win, text='Введите конец массива b = ').grid(column=1,row=2)
tk.Label(win, text='Введите количество точек массива: ').grid(column=1,row=3)
tk.Label(win, text='Центр маски по x от a = ').grid(column=1,row=4)
tk.Label(win, text='Центр маски по y до b = ').grid(column=1,row=5)
tk.Label(win, text='Радиус маски r = ').grid(column=1,row=6)
q.grid(column=2,row=1)
w.grid(column=2,row=2)
e.grid(column=2,row=3)
t.grid(column=2,row=4)
u.grid(column=2,row=5)
i.grid(column=2,row=6)
tk.Button(win, text='Ввести точки', command=draw_graph).grid(column=2,row=7)
Почитайте побольше о размещении виджетов в tkinter
А какой график при этих введенных данных должен получиться?
Автор решения: Костя Килиманов
→ Ссылка
Почитал по поводу создания различных графиков в Matplotlib тут: https://devpractice.ru/matplotlib-lesson-5-1-mplot3d-toolkit/#p4
В соответствие с информацией о построение графиков "Поверхность" изменил отрисовку осей:
ax = fig.add_subplot(111, projection='3d')
cmap = LinearSegmentedColormap.from_list('red_blue', ['b', 'g', 'y', 'r'], 256)
ax.plot_surface(x, y, z *(1 + mask * 0.75), cmap=cmap)
В общем виде код выглядит так:
import numpy as np
import tkinter as tk
from matplotlib.figure import Figure
from matplotlib.colors import LinearSegmentedColormap
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
win = tk.Tk()
win.geometry ('900x900+600+300')
def draw_graph():
x, y, z, X, Y, mask = makeData()
global canvas1
if canvas1:
canvas1.get_tk_widget().destroy()
fig = Figure(figsize=(10, 6), dpi=100)
canvas1 = FigureCanvasTkAgg(fig, master = win)
canvas1.draw()
ax = fig.add_subplot(111, projection='3d')
cmap = LinearSegmentedColormap.from_list('red_blue', ['b', 'g', 'y', 'r'], 256)
ax.plot_surface(x, y, z *(1 + mask * 0.75), cmap=cmap)
toolbar = NavigationToolbar2Tk(canvas1, win)
toolbar.update()
canvas1.get_tk_widget().pack(side=tk.TOP, fill=tk.NONE, expand=0)
win.after(200, None)
def makeData():
a=int(q.get()) #19
b=float(w.get()) #20
c=int(e.get()) #200
x0=float(t.get()) #19.3
y0=float(u.get()) #19.6
r=float(i.get()) #.1
x = np.linspace(a, b, c) # создаем массив из 100 чисел float от 19 до 20 с равномернов шагом
y = np.linspace(a, b, c)
xgrid, ygrid = np.meshgrid(x, y)
z = np.random.normal(xgrid, ygrid)
r = .1 # радиус маски
X, Y = np.meshgrid(x, y)
mask = (X - x0) ** 2 + (Y - y0) ** 2 < r ** 2
return xgrid, ygrid, z, X, Y, mask
canvas1 = None
tk.Label(win, text='Введите начало массива a = ').pack(padx = 5, pady = 5)
tk.Label(win, text='Введите конец массива b = ').pack(padx = 5, pady = 5)
tk.Label(win, text='Введите количество точек массива: ').pack(padx = 5, pady = 5)
tk.Label(win, text='Центр маски по x от a = ').pack(padx = 5, pady = 5)
tk.Label(win, text='Центр маски по y до b = ').pack(padx = 5, pady = 5)
tk.Label(win, text='Радиус маски r = ').pack(padx = 5, pady = 5)
q = tk.Entry()
w = tk.Entry()
e = tk.Entry()
t = tk.Entry()
u = tk.Entry()
i = tk.Entry()
q.pack(padx = 5, pady = 5)
w.pack(padx = 5, pady = 5)
e.pack(padx = 5, pady = 5)
t.pack(padx = 5, pady = 5)
u.pack(padx = 5, pady = 5)
i.pack(padx = 5, pady = 5)
tk.Button(win, text='Ввести точки', command=draw_graph).pack(padx = 5, pady = 5)
win.mainloop()
