Home > Blockchain >  PyQt and Netgraph Interactive Graph
PyQt and Netgraph Interactive Graph

Time:03-25

I have an application with PyQt and I would like to add the Netgraph graphs interactiviness to my application.

However, I am not being able to click the vertex and edges of the graph.

Here is a minimal example:

import sys

import matplotlib
import matplotlib.pyplot as plt

from netgraph import InteractiveGraph

from PyQt5 import QtWidgets

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT
from matplotlib.figure import Figure

import networkx as nx

matplotlib.use('Qt5Agg')


class MplCanvas(FigureCanvasQTAgg):

    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)

        g = nx.house_x_graph()

        fig, ax = plt.subplots(figsize=(10, 10))

        plot_instance = InteractiveGraph(g)

        super(MplCanvas, self).__init__(fig)


class MainWindow(QtWidgets.QMainWindow):

    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        sc = MplCanvas(self, width=5, height=4, dpi=100)

        toolbar = NavigationToolbar2QT(sc, self)

        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(toolbar)
        layout.addWidget(sc)

        widget = QtWidgets.QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)

        self.show()


app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
app.exec_()

And here is an example with the behavior I want:

import matplotlib.pyplot as plt
import networkx as nx
from netgraph import EditableGraph

g = nx.house_x_graph()


fig, ax = plt.subplots(figsize=(10, 10))

plot_instance = EditableGraph(g)

plt.show()

Any ideas how I can make Netgraph interactiviness work along with PyQt?

CodePudding user response:

There are several errors but the most important are:

  • You must use the same figure from the canvas, and not create a new one using pyplot.
  • You have to pass the Axes as an argument to InteractiveGraph so that it uses the already created figure.
  • Save the instance of InteractiveGraph as an attribute of the class.
import sys

from PyQt5 import QtWidgets

import matplotlib

matplotlib.use("Qt5Agg")


from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT
from matplotlib.figure import Figure

from netgraph import InteractiveGraph

import networkx as nx


class MplCanvas(FigureCanvasQTAgg):
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        super(MplCanvas, self).__init__(Figure(figsize=(width, height), dpi=dpi))
        self.setParent(parent)
        self.ax = self.figure.add_subplot(111)
        graph = nx.house_x_graph()
        self.plot_instance = InteractiveGraph(graph, ax=self.ax)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.canvas = MplCanvas(self, width=5, height=4, dpi=100)
        self.toolbar = NavigationToolbar2QT(self.canvas, self)

        widget = QtWidgets.QWidget()
        self.setCentralWidget(widget)

        layout = QtWidgets.QVBoxLayout(widget)
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)


def main():
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    app.exec_()


if __name__ == "__main__":
    main()
  • Related