PyQt 嵌入式 matplotlib 中不显示 networkx 图的边标签
Edge labels of networkx graph don't show in PyQt embedded matplotlib
我有一个显示在 PyQt5 应用程序中的 networkx 有向图,它工作得很好。
为了方便起见,我现在正尝试将标签添加到边缘,但无法使它们出现。
下面是一个复制问题的虚拟应用程序:
import sys
from PyQt5 import QtCore, QtWidgets
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.pyplot import Figure
import networkx as nx
class data_tab(QtWidgets.QWidget):
def __init__(self, parent, title):
QtWidgets.QWidget.__init__(self, parent)
self.data_tab_glayout = QtWidgets.QGridLayout(self)
self.canvas = FigureCanvas(Figure(figsize=(5, 3)))
self.canvas_vlayout = QtWidgets.QVBoxLayout(self.canvas)
self.data_tab_glayout.addWidget(self.canvas, 0, 0, 2, 1)
self.axe = self.canvas.figure.add_subplot(111)
self.canvas.figure.subplots_adjust(left=0.025, top=0.965, bottom=0.040, right=0.975)
# add the tab to the parent
parent.addTab(self, "")
# set text name
parent.setTabText(parent.indexOf(self), title)
class spec_writer(QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
self.showMaximized()
self.centralwidget = QtWidgets.QWidget(self)
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.core_tab = QtWidgets.QTabWidget(self.centralwidget)
self.verticalLayout.addWidget(self.core_tab)
self.add_tab_btn = QtWidgets.QPushButton(self.centralwidget)
self.verticalLayout.addWidget(self.add_tab_btn)
self.refresh_tab_btn = QtWidgets.QPushButton(self.centralwidget)
self.verticalLayout.addWidget(self.refresh_tab_btn)
self.setCentralWidget(self.centralwidget)
self.add_tab_btn.setText("Add Tab")
self.refresh_tab_btn.setText("Refresh Tabs")
self.core_tab.setEnabled(True)
self.core_tab.setTabShape(QtWidgets.QTabWidget.Rounded)
self.core_tab.setElideMode(QtCore.Qt.ElideNone)
self.core_tab.setDocumentMode(False)
self.core_tab.setTabsClosable(True)
self.core_tab.setMovable(True)
self.core_tab.setTabBarAutoHide(False)
self.tab_counter = 0
self.random_tabs = [("a", ["b", "c"]),
("d", ["e", "f", "g"]),
("h", ["i", "j", "k", "l"]),
("m", ["n"]),
("o", ["p", "q"]),
("r", ["s", "t", "u", "v", "w", "x", "y", "z"])]
self.add_tab_btn.clicked.connect(self.openRandomTab)
self.refresh_tab_btn.clicked.connect(self.refreshAllTabs)
def openRandomTab(self):
tab = data_tab(self.core_tab, "test " + str(self.tab_counter))
self._drawDataGraph(self.tab_counter % len(self.random_tabs), tab)
self.tab_counter += 1
self.core_tab.setCurrentIndex(self.core_tab.indexOf(tab))
def _drawDataGraph(self, tabNb, dataWidget):
dataWidget.axe.cla()
# 1. draw graph
producer = self.random_tabs[tabNb][0]
consumers = self.random_tabs[tabNb][1]
color_map = []
DG = nx.DiGraph()
for cons in consumers:
DG.add_edge(producer, cons, label="labeltest1")
for i in range(len(DG.nodes())):
if i < 1 + len(consumers):
color_map.append("#DCE46F")
else:
color_map.append("#6FA2E4")
pos = nx.shell_layout(DG)
labels = nx.get_edge_attributes(DG, 'label')
nx.draw(DG, pos, node_color=color_map, with_labels=True, font_size=8, node_size=1000, node_shape='o', ax= dataWidget.axe)
nx.draw_networkx_edge_labels(DG, pos, edge_labels=labels)
dataWidget.canvas.draw()
def refreshAllTabs(self):
# loop through all pages and associated to get
for tab_index in range(self.core_tab.count()):
data_tab_widget = self.core_tab.widget(tab_index)
# draw graph
self._drawDataGraph(tab_index % len(self.random_tabs), data_tab_widget)
sys.argv = ['']
app = QtWidgets.QApplication(sys.argv)
cbtc_spec_writer = spec_writer()
cbtc_spec_writer.show()
app.exec_()
我不知道要显示的标签是什么,但是当我执行未嵌入 pyqt5 应用程序的相同代码时(因此直接使用 plt.show()),它可以正常工作。所以我想我的 canvas 设置中缺少某些东西。
编辑:下面是我想要获得的,但嵌入在 PyQt5 应用程序中。目前标签“labeltest1”不会显示
您还必须将坐标轴传递给 draw_networkx_edge_labels。除此之外,我重写了您的代码以使其更具可读性。
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
QApplication,
QMainWindow,
QPushButton,
QTabWidget,
QVBoxLayout,
QWidget,
)
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import networkx as nx
class DataTab(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
layout = QVBoxLayout(self)
self.canvas = FigureCanvas(Figure(figsize=(5, 3)))
layout.addWidget(self.canvas)
self.ax = self.canvas.figure.add_subplot(111)
self.canvas.figure.subplots_adjust(
left=0.025, top=0.965, bottom=0.040, right=0.975
)
class SpecWriter(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.core_tab = QTabWidget(
tabShape=QTabWidget.Rounded,
elideMode=Qt.ElideNone,
documentMode=False,
tabsClosable=True,
movable=True,
tabBarAutoHide=False,
)
self.add_tab_btn = QPushButton("Add Tab")
self.refresh_tab_btn = QPushButton("Refresh Tabs")
self.centralwidget = QWidget(self)
layout = QVBoxLayout(self.centralwidget)
layout.addWidget(self.core_tab)
layout.addWidget(self.add_tab_btn)
layout.addWidget(self.refresh_tab_btn)
self.setCentralWidget(self.centralwidget)
self.random_tabs = [
("a", ["b", "c"]),
("d", ["e", "f", "g"]),
("h", ["i", "j", "k", "l"]),
("m", ["n"]),
("o", ["p", "q"]),
("r", ["s", "t", "u", "v", "w", "x", "y", "z"]),
]
self.add_tab_btn.clicked.connect(self.open_random_tab)
self.refresh_tab_btn.clicked.connect(self.refresh_all_tabs)
def update_graph(self, ax, tabNb):
ax.clear()
producer, consumers = self.random_tabs[tabNb]
color_map = []
DG = nx.DiGraph()
for cons in consumers:
DG.add_edge(producer, cons, label="labeltest1")
for i, _ in enumerate(DG.nodes()):
color_map.append("#DCE46F" if i < 1 + len(consumers) else "#6FA2E4")
pos = nx.shell_layout(DG)
labels = nx.get_edge_attributes(DG, "label")
nx.draw(
DG,
pos,
node_color=color_map,
with_labels=True,
font_size=8,
node_size=1000,
node_shape="o",
ax=ax,
)
nx.draw_networkx_edge_labels(DG, pos, edge_labels=labels, ax=ax)
ax.figure.canvas.draw()
def open_random_tab(self):
i = self.core_tab.count()
title = f"Test {i}"
data_tab_widget = DataTab()
self.update_graph(data_tab_widget.ax, i % len(self.random_tabs))
self.core_tab.addTab(data_tab_widget, title)
self.core_tab.setCurrentIndex(i)
def refresh_all_tabs(self):
for tab_index in range(self.core_tab.count()):
data_tab_widget = self.core_tab.widget(tab_index)
self.update_graph(data_tab_widget.ax, tab_index % len(self.random_tabs))
def main():
import sys
app = QApplication([])
w = SpecWriter()
w.showMaximized()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
我有一个显示在 PyQt5 应用程序中的 networkx 有向图,它工作得很好。 为了方便起见,我现在正尝试将标签添加到边缘,但无法使它们出现。
下面是一个复制问题的虚拟应用程序:
import sys
from PyQt5 import QtCore, QtWidgets
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.pyplot import Figure
import networkx as nx
class data_tab(QtWidgets.QWidget):
def __init__(self, parent, title):
QtWidgets.QWidget.__init__(self, parent)
self.data_tab_glayout = QtWidgets.QGridLayout(self)
self.canvas = FigureCanvas(Figure(figsize=(5, 3)))
self.canvas_vlayout = QtWidgets.QVBoxLayout(self.canvas)
self.data_tab_glayout.addWidget(self.canvas, 0, 0, 2, 1)
self.axe = self.canvas.figure.add_subplot(111)
self.canvas.figure.subplots_adjust(left=0.025, top=0.965, bottom=0.040, right=0.975)
# add the tab to the parent
parent.addTab(self, "")
# set text name
parent.setTabText(parent.indexOf(self), title)
class spec_writer(QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
self.showMaximized()
self.centralwidget = QtWidgets.QWidget(self)
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.core_tab = QtWidgets.QTabWidget(self.centralwidget)
self.verticalLayout.addWidget(self.core_tab)
self.add_tab_btn = QtWidgets.QPushButton(self.centralwidget)
self.verticalLayout.addWidget(self.add_tab_btn)
self.refresh_tab_btn = QtWidgets.QPushButton(self.centralwidget)
self.verticalLayout.addWidget(self.refresh_tab_btn)
self.setCentralWidget(self.centralwidget)
self.add_tab_btn.setText("Add Tab")
self.refresh_tab_btn.setText("Refresh Tabs")
self.core_tab.setEnabled(True)
self.core_tab.setTabShape(QtWidgets.QTabWidget.Rounded)
self.core_tab.setElideMode(QtCore.Qt.ElideNone)
self.core_tab.setDocumentMode(False)
self.core_tab.setTabsClosable(True)
self.core_tab.setMovable(True)
self.core_tab.setTabBarAutoHide(False)
self.tab_counter = 0
self.random_tabs = [("a", ["b", "c"]),
("d", ["e", "f", "g"]),
("h", ["i", "j", "k", "l"]),
("m", ["n"]),
("o", ["p", "q"]),
("r", ["s", "t", "u", "v", "w", "x", "y", "z"])]
self.add_tab_btn.clicked.connect(self.openRandomTab)
self.refresh_tab_btn.clicked.connect(self.refreshAllTabs)
def openRandomTab(self):
tab = data_tab(self.core_tab, "test " + str(self.tab_counter))
self._drawDataGraph(self.tab_counter % len(self.random_tabs), tab)
self.tab_counter += 1
self.core_tab.setCurrentIndex(self.core_tab.indexOf(tab))
def _drawDataGraph(self, tabNb, dataWidget):
dataWidget.axe.cla()
# 1. draw graph
producer = self.random_tabs[tabNb][0]
consumers = self.random_tabs[tabNb][1]
color_map = []
DG = nx.DiGraph()
for cons in consumers:
DG.add_edge(producer, cons, label="labeltest1")
for i in range(len(DG.nodes())):
if i < 1 + len(consumers):
color_map.append("#DCE46F")
else:
color_map.append("#6FA2E4")
pos = nx.shell_layout(DG)
labels = nx.get_edge_attributes(DG, 'label')
nx.draw(DG, pos, node_color=color_map, with_labels=True, font_size=8, node_size=1000, node_shape='o', ax= dataWidget.axe)
nx.draw_networkx_edge_labels(DG, pos, edge_labels=labels)
dataWidget.canvas.draw()
def refreshAllTabs(self):
# loop through all pages and associated to get
for tab_index in range(self.core_tab.count()):
data_tab_widget = self.core_tab.widget(tab_index)
# draw graph
self._drawDataGraph(tab_index % len(self.random_tabs), data_tab_widget)
sys.argv = ['']
app = QtWidgets.QApplication(sys.argv)
cbtc_spec_writer = spec_writer()
cbtc_spec_writer.show()
app.exec_()
我不知道要显示的标签是什么,但是当我执行未嵌入 pyqt5 应用程序的相同代码时(因此直接使用 plt.show()),它可以正常工作。所以我想我的 canvas 设置中缺少某些东西。
编辑:下面是我想要获得的,但嵌入在 PyQt5 应用程序中。目前标签“labeltest1”不会显示
您还必须将坐标轴传递给 draw_networkx_edge_labels。除此之外,我重写了您的代码以使其更具可读性。
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
QApplication,
QMainWindow,
QPushButton,
QTabWidget,
QVBoxLayout,
QWidget,
)
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import networkx as nx
class DataTab(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
layout = QVBoxLayout(self)
self.canvas = FigureCanvas(Figure(figsize=(5, 3)))
layout.addWidget(self.canvas)
self.ax = self.canvas.figure.add_subplot(111)
self.canvas.figure.subplots_adjust(
left=0.025, top=0.965, bottom=0.040, right=0.975
)
class SpecWriter(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.core_tab = QTabWidget(
tabShape=QTabWidget.Rounded,
elideMode=Qt.ElideNone,
documentMode=False,
tabsClosable=True,
movable=True,
tabBarAutoHide=False,
)
self.add_tab_btn = QPushButton("Add Tab")
self.refresh_tab_btn = QPushButton("Refresh Tabs")
self.centralwidget = QWidget(self)
layout = QVBoxLayout(self.centralwidget)
layout.addWidget(self.core_tab)
layout.addWidget(self.add_tab_btn)
layout.addWidget(self.refresh_tab_btn)
self.setCentralWidget(self.centralwidget)
self.random_tabs = [
("a", ["b", "c"]),
("d", ["e", "f", "g"]),
("h", ["i", "j", "k", "l"]),
("m", ["n"]),
("o", ["p", "q"]),
("r", ["s", "t", "u", "v", "w", "x", "y", "z"]),
]
self.add_tab_btn.clicked.connect(self.open_random_tab)
self.refresh_tab_btn.clicked.connect(self.refresh_all_tabs)
def update_graph(self, ax, tabNb):
ax.clear()
producer, consumers = self.random_tabs[tabNb]
color_map = []
DG = nx.DiGraph()
for cons in consumers:
DG.add_edge(producer, cons, label="labeltest1")
for i, _ in enumerate(DG.nodes()):
color_map.append("#DCE46F" if i < 1 + len(consumers) else "#6FA2E4")
pos = nx.shell_layout(DG)
labels = nx.get_edge_attributes(DG, "label")
nx.draw(
DG,
pos,
node_color=color_map,
with_labels=True,
font_size=8,
node_size=1000,
node_shape="o",
ax=ax,
)
nx.draw_networkx_edge_labels(DG, pos, edge_labels=labels, ax=ax)
ax.figure.canvas.draw()
def open_random_tab(self):
i = self.core_tab.count()
title = f"Test {i}"
data_tab_widget = DataTab()
self.update_graph(data_tab_widget.ax, i % len(self.random_tabs))
self.core_tab.addTab(data_tab_widget, title)
self.core_tab.setCurrentIndex(i)
def refresh_all_tabs(self):
for tab_index in range(self.core_tab.count()):
data_tab_widget = self.core_tab.widget(tab_index)
self.update_graph(data_tab_widget.ax, tab_index % len(self.random_tabs))
def main():
import sys
app = QApplication([])
w = SpecWriter()
w.showMaximized()
sys.exit(app.exec_())
if __name__ == "__main__":
main()