#python #numpy #tkinter #graph #networkx
#python #numpy #tkinter #График #networkx
Вопрос:
Я пытаюсь заставить свою программу читать матрицу, которая может быть введена пользователем, и построить этот график где-нибудь в корне. Итак, мы можем задать количество точек на нашем графике, затем мы можем получить пустую матрицу для вставки наших отношений между точками. После этого я могу отправить свои значения, и они верны, но когда я пытаюсь построить график, всегда возникают ошибки, исправление которых создает новые ошибки.
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt
import tkinter as tk
import networkx as nx
import numpy as np
class SimpleTableInput(tk.Frame):
def __init__(self, parent, rows, columns):
tk.Frame.__init__(self, parent)
self._entry = {}
self.rows = rows
self.columns = columns
for row in range(self.rows):
for column in range(self.columns):
index = (row, column)
e = tk.Entry(self)
e.grid(row=row, column=column, stick="nsew")
e.insert(0, '0')
self._entry[index] = e
for column in range(self.columns):
self.grid_columnconfigure(column, weight=1)
self.grid_rowconfigure(rows, weight=1)
def get(self):
result = []
for row in range(self.rows):
current_row = []
for column in range(self.columns):
index = (row, column)
current_row.append(self._entry[index].get())
result.append(current_row)
self.matrix = np.array(result)
return result
class Example(tk.Frame):
def __init__(self, parent, n):
tk.Frame.__init__(self, parent)
self.table = SimpleTableInput(self, n, n)
self.submit = tk.Button(self, text="Submit", command=self.on_submit)
self.table.pack(side="top", fill="both", expand=True)
self.submit.pack(side="bottom")
def on_submit(self):
print(self.table.get())
matrix = self.table.get()
matrix = np.array(matrix)
def build_graph():
f = plt.figure(figsize=(5, 4))
plt.axis('off')
G = nx.from_numpy_array(matrix)
pos = nx.circular_layout(G)
nx.draw_networkx(G, pos=pos)
canvas = FigureCanvasTkAgg(f, master=root)
canvas.get_tk_widget().pack(side=Tk.bottom, fill=Tk.BOTH, expand=1)
def create_matrix():
n = int(e1.get())
table = Example(root, n).pack(side="left")
b2 = tk.Button(root, text="build_graph", command=build_graph)
b2.pack(side='bottom')
root = tk.Tk()
b1 = tk.Button(root, text="Number of points", command=create_matrix)
e1 = tk.Entry(root)
e1.insert(0, '0')
b1.pack(side='right')
e1.pack(side='right')
matrix = []
root.mainloop()
Я новичок в tkinter, поэтому всегда есть ошибки, я не могу исправить правильно, например, сейчас я получаю:
«Ошибка атрибута: объект ‘list’ не имеет атрибута ‘shape'»
Как я могу исправить это правильно?
Или, может быть, мне нужно начать с другой библиотеки графического интерфейса на python для таких задач?
Комментарии:
1. всегда указывайте полное сообщение об ошибке (трассировка) в вопросе (в виде текста, а не скриншота). Есть и другая полезная информация.
2. ошибка означает, что у вас стандартный список, а не массив numpy или другой массив. Список не имеет формы метода. Проверьте, что у вас есть
type(your_object)
и преобразуйте это в массив. Другой графический интерфейс не решит эту проблему, потому что это проблема НЕ с графическим интерфейсом, а с вашими данными. И всегда помещайте ПОЛНОЕ сообщение об ошибке (начиная с обратной трассировки работы), а не только последнюю строку. Есть информация, какая строка кода создает проблему.
Ответ №1:
Вы используете список для создания графика, но он необходим np.array
.
В build_graph
вы должны получить table
из Example
и преобразовать в массив
def build_graph():
#global table
matrix = table.table.get()
matrix = np.array(matrix)
(вы используете имя, table
например Example
, которое имеет таблицу свойств, поэтому вы получаете table.table
, и это может быть ошибка)
Есть и другие проблемы
table
in create_graph
является локальной переменной, поэтому вы не можете получить к ней доступ вне этой функции. Вам нужно global
создать глобальную переменную
def create_matrix():
global table
Далее вы сталкиваетесь с распространенной ошибкой
table = Example().pack()
Он присваивается None
переменной table
, потому что pack()
возвращает None
table = Example()
table.pack()
Есть небольшая ошибка с, side=Tk.bottom, fill=Tk.both
потому что вам нужно tk
вместо Tk
или вы можете использовать строки side="bottom", fill="both"
Наконец-то я получаю этот график.
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt
import tkinter as tk
import networkx as nx
import numpy as np
class SimpleTableInput(tk.Frame):
def __init__(self, parent, rows, columns):
tk.Frame.__init__(self, parent)
self._entry = {}
self.rows = rows
self.columns = columns
for row in range(self.rows):
for column in range(self.columns):
index = (row, column)
e = tk.Entry(self)
e.grid(row=row, column=column, stick="nsew")
e.insert(0, '0')
self._entry[index] = e
for column in range(self.columns):
self.grid_columnconfigure(column, weight=1)
self.grid_rowconfigure(rows, weight=1)
def get(self):
result = []
for row in range(self.rows):
current_row = []
for column in range(self.columns):
index = (row, column)
current_row.append(self._entry[index].get())
result.append(current_row)
self.matrix = np.array(result)
return result
class Example(tk.Frame):
def __init__(self, parent, n):
tk.Frame.__init__(self, parent)
self.table = SimpleTableInput(self, n, n)
self.submit = tk.Button(self, text="Submit", command=self.on_submit)
self.table.pack(side="top", fill="both", expand=True)
self.submit.pack(side="bottom")
def on_submit(self):
matrix = self.table.get()
matrix = np.array(matrix)
print(matrix)
def build_graph():
#global table
matrix = table.table.get()
matrix = np.array(matrix)
f = plt.figure(figsize=(5, 4))
plt.axis('off')
G = nx.from_numpy_array(matrix)
pos = nx.circular_layout(G)
nx.draw_networkx(G, pos=pos)
canvas = FigureCanvasTkAgg(f, master=root)
canvas.get_tk_widget().pack(side='bottom', fill='both', expand=1) # ERROR Tk.
def create_matrix():
global table
n = int(e1.get())
table = Example(root, n) # .pack(side="left") ERROR
table.pack(side="left")
b2 = tk.Button(root, text="Build Graph", command=build_graph)
b2.pack(side='bottom')
root = tk.Tk()
b1 = tk.Button(root, text="Number of points", command=create_matrix)
e1 = tk.Entry(root)
e1.insert(0, '0')
b1.pack(side='right')
e1.pack(side='right')
matrix = []
root.mainloop()
Комментарии:
1. Это работает, спасибо. Но этот код строит только клики (полный график), но это уже другая проблема)
2. если у вас возникла новая проблема, создайте новый вопрос на новой странице — у вас будет больше места для размещения кода, полного сообщения об ошибке и описания.