PyQt integrates well with matplotlib collections, so that collections created through the pandapower plotting module can be embedded into PyQt widgets to create interactive plots or even whole applications.
This is an example for a slider widget that allows to change the scaling of load and generation in the grid and analyse the power flows in the network in real time. The buses can also be clicked on for a little info window:
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import pandapower.plotting as plot
import pandapower as pp
import matplotlib.pyplot as plt
class SliderWidget(QWidget):
def __init__(self, net):
super().__init__()
self.net = net
self.layout = QVBoxLayout()
self.initialize_netplot()
self.initialize_slider()
self.setWindowTitle("PyQt with pandapower Demo")
self.setLayout(self.layout)
def initialize_netplot(self):
self.net.line_geodata.drop(set(net.line_geodata.index) - set(net.line.index), inplace=True)
cmap, norm = plot.cmap_continuous([(0.97, "blue"), (1.0, "green"), (1.03, "red")])
self.bc = plot.create_bus_collection(net, size=90, zorder=2, cmap=cmap, norm=norm, picker=True,
infofunc=lambda x: "This is bus %s"%net.bus.name.at[x])
cmap, norm = plot.cmap_continuous([(20, "green"), (50, "yellow"), (60, "red")])
self.lc = plot.create_line_collection(net, zorder=1, cmap=cmap, norm=norm, linewidths=2,
infofunc=lambda x: "This is line %s"%net.line.name.at[x])
self.fig, self.ax = plt.subplots()
plot.draw_collections([self.bc, self.lc], ax=self.ax)
plt.close()
self.canvas = FigureCanvas(self.fig)
self.canvas.mpl_connect('pick_event', self.pick_event)
self.canvas.draw()
self.canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.layout.addWidget(self.canvas)
def initialize_slider(self):
self.sliders = {}
for element in ["load", "sgen"]:
frame = QWidget()
layout = QHBoxLayout()
layout.addWidget(QLabel("scaling %s"%element))
self.sliders[element] = QSlider(Qt.Horizontal, value=50)
self.sliders[element].valueChanged.connect(self.slider_changed)
layout.addWidget(self.sliders[element])
frame.setLayout(layout)
self.layout.addWidget(frame)
def slider_changed(self):
for element, slider in self.sliders.items():
self.net[element].scaling = slider.value() / 100.
pp.runpp(self.net)
self.ax.collections[0].set_array(self.net.res_bus.vm_pu.values)
self.ax.collections[1].set_array(self.net.res_line.loading_percent.values)
self.canvas.draw()
def pick_event(self, event):
idx = event.ind[0]
collection = event.artist
self.info = QLabel()
self.info.setText(collection.info[idx])
self.info.show()
--------------------------------------------------------------------------- ModuleNotFoundError Traceback (most recent call last) <ipython-input-2-8480eeafbcaf> in <module> 1 import sys ----> 2 from PyQt4.QtCore import * 3 from PyQt4.QtGui import * 4 from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas 5 ModuleNotFoundError: No module named 'PyQt4'
def main(net):
app = QApplication(sys.argv)
ex = SliderWidget(net)
ex.showMaximized()
sys.exit(app.exec_())
from pandapower.networks import mv_oberrhein
net = mv_oberrhein()
main(net)
An exception has occurred, use %tb to see the full traceback. SystemExit: 0
D:\Python\Anaconda\lib\site-packages\IPython\core\interactiveshell.py:2971: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.