
Учебники / 0841558_16EA1_federico_milano_power_system_modelling_and_scripting
.pdf


476 |
22 Visualization Matters |
5.The command-line approach can provide a finer tuning than GUI-based ones.
6.Due to the lack of a user-friendly interface, the user is forced to carefully study the command-line options that, in turn, leads to a better understanding of the application functioning.
GUIs are compatible with the command-line approach but only if the GUI is maintained strictly separated from the main application that performs the operations. GUIs built on top of an existing command-line application are often called skins. The advantage of separating the skin from the kernel application is twofold: (i) the user can chose if using the GUI or not, and (ii) several skins can be built for the same application.2 In conclusion, the command line approach results in more flexibility and more freedom for the user.
Unfortunately, few power system applications have adopted the e cient command-line approach, e.g., [42, 363], and very few have provided a command-line version and a separate skin [195]. This is probably due to the fact that most power system software packages are proprietary applications and works only on Microsoft R operating systems.
Script 22.1 Batch Script for Power Flow Analysis
Batch scripting is a powerful technique that consists in executing a series of operations in a non-interactive way. All commands are stored in a file (batch script) and then the file executed. Batch scripting can be considered a sort of meta-programming.
Python provides an easy way to take advantage of batch scripting. In fact any Python procedure can be distributed as a library rather than as stand-alone applications.3 Since Python libraries can be imported by any Python script, the same Python language can be used for creating batch files. This technique is illustrated in the script below, which produces the results presented in Example 4.4 of Chapter 4.
The script works as follows. For the sake of example, assume that the power flow analysis tool described in Script 3.2 of Chapter 3 is available as a Python library called powerlib. Thus, importing this library provides all classes and routines described in Parts II and III. For example, settings can be adjusted using the attributes of the powerlib.system.Settings class (see Script 3.2 for further details on the architecture of the system structure).
In the example below, the main data file is ieee14.dm that, apart from the power flow data, contains the statement:
INCLUDE, load.txt
2This explains why, for example, there exist several window managers for Linux systems, while Windows system have an unique user interface.
3The setuptools library allows creating custom libraries in few easy steps.
22.1 Graphical Interface vs. Command Line Approach |
477 |
This command imposes that the parser reads a file called load.txt (see Example 21.1 and Script 21.1 of Chapter 21 for further details on INCLUDE statement). Then the script calls repeatedly the solution of the power flow analysis changing the load level in the file load.txt. The load level is modified through the ALTER statement (see again Example 21.1 for details). Finally results are plotted and saved to a file using the Matplotlib library.
import powerlib import numpy
from cvxopt.base import matrix, div from matplotlib import pyplot
def run():
load = numpy.linspace(0.6, 2.6, num=50, endpoint=True) a = []
b = []
powerlib.system.Settings.pv2pq = False powerlib.system.Settings.pq2z = False
powerlib.system.Settings.pfsolver = ’NR’ for m in load:
powerlib.system.Settings.iteration = 0 fid = open(’load.txt’, ’wt’)
fid.write(’ALTER, PQ, MUL, *, p, %.5f\n’ % m) fid.write(’ALTER, PQ, MUL, *, q, %.5f\n’ % m) fid.close()
powerlib.run(’ieee14.dm’, path=’tests/powerlib’) vec = powerlib.system.DAE.y[powerlib.system.Bus.a] a.append(vec)
powerlib.system.Settings.pfsolver = ’DC’ for m in load:
powerlib.system.Settings.iteration = 0 fid = open(’load.txt’, ’wt’)
fid.write(’ALTER, PQ, MUL, *, p, %.5f\n’ % m) fid.write(’ALTER, PQ, MUL, *, q, %.5f\n’ % m) fid.close()
powerlib.run(’ieee14.dm’, path=’tests’)
vec = powerlib.system.DAE.y[powerlib.system.Bus.a] b.append(vec)
n = load.size
c = matrix(0, (n, 1), ’d’) d = matrix(0, (n, 1), ’d’) m = matrix(load)
for i, ai, bi in zip(range(n), a, b): am = matrix(ai)
bm = matrix(bi) ad = matrix(ai) ad[0] = 1.0
er = 100*div(abs(am - bm), abs(ad))
478 |
|
22 Visualization Matters |
|
d[i] |
= max(er) |
|
c[i] |
= sum(er)/(n - 1) |
fig = pyplot.figure() pyplot.hold(True)
pyplot.plot(m, c, ’k’, label=’mean error’) pyplot.plot(m, d, ’k:’, label=’max error’) pyplot.legend(loc=’upper left’) pyplot.xlabel(’load’) pyplot.ylabel(’error’) pyplot.xlim([min(m), max(m)])
pyplot.savefig(’dcerror.eps’, format=’eps’) pyplot.show()
22.2Result Visualization
The importance of an intuitive and fully informative visualization of power system results has been recognized and formalized in early nineties. In [180], the authors specify three guidelines for setting up a good graphical representation of physical phenomena: (i) natural encoding of information; (ii) task specific graphics; and (iii) no gratuitous graphics. In [225, 346], twodimensional contour plots are proposed for the visualization of voltage bus levels with inclusion of the topological information of the network. Standard two-dimensional plots, temperature maps and three-dimensional plots and geographical information systems comply with the three guidelines mentioned above and are described in the following subsections.
22.2.1Standard Two-Dimensional Plots
Standard two-dimensional (2D) plots are extensively used throughout the whole book. Moreover, the features of this visualization technique are very well-known. This subsection only describes an e cient approach for manipulating simulations results.
One of the most important strengths of UNIX systems is that every manipulable object is a file. Using this concept, UNIX system has proved to be the most adequate for scientific applications. A standard UNIX application can be launched from the command line and accepts files for both input data and settings and then provides the output as a set of files. For example, the LATEX compiler accepts as input .tex files and provides as outputs a .dvi file. Then, the .dvi file can be viewed as is or translated into postscript or pdf formats by other applications.
Following the UNIX teaching, the outputs of a power system analysis tool, such as time domain simulations or continuation power flow analysis, can be conveniently exported as plain ASCII files. For example, one file can report variable values in columns and another file can specify to which variable each

22.2 Result Visualization |
479 |
column corresponds. Then the two files can be parsed and results plotted according to user settings.
This approach provides several advantages with respect to a all-in-one approach which is the standard of most power system applications. In particular, the main advantage is the possibility of keeping the application that performs the simulation separated from the application that plots results. This provides more freedom, similarly to the command-line/skin approach described in previous Section 22.1.
Script 22.2 Parser for Simulations Results
The following script provides an example of parser for simulation results. The parser reads one or more files, stores the specified values in lists and finally calls a plot function that actually creates the 2D plot. The syntax for calling the script for the command line is as follows:
parse results [-options] datafile1 listfile1 x y1 [y2 y3 ...]
[datafile2 listfile2 x y1 [y2 y3 ...]] ...
where x is the number the variable used for the x-axis and y1, y2, etc., are the numbers of the variables used for the y-axis.
import os import re import sys
from optparse import OptionParser
def parse results():
parser = OptionParser()
parser.add option(’-p’, ’--path’, dest=’path’,
default=cwd, help=’Path of the data file’) parser.add option(’-l’, ’--legend’, dest=’legend’,
action=’store true’, default=False, help=’Add legend to the plot’)
parser.add option(’-g’, ’--grid’, dest=’grid’, action=’store true’, default=False, help=’Add grid to the plot’)
parser.add option(’-s’, ’--style’, dest=’style’, default=’colors’, help=plotstyle)
parser.add option(’-y’, ’--ylabel’, dest=’ylabel’, default=None, help=’Label for the y axis’)
parser.add option(’-k’, ’--position’, dest=’position’, default=’lower right’, help=legendhelp)
options, args = parser.parse args(sys.argv[1:])
# set up arguments if len(args) == 0:
print ’* Error: At least one data file must be defined!’ sys.exit(1)

22.2 Result Visualization |
481 |
mapy = map(yidx.index, ysorted) yname temp = yname[:]
for idx, item in enumerate(mapy): yname[idx] = yname temp[item]
fid.close()
# scan data file
fid = open(datafile, ’r’)
xx= [[] for x in range(len(xyidx) - 1)]
yy= [[] for y in range(len(xyidx) - 1)]
""" Note: xx = [[]]*(len(xyidx) - 1) does not work since each element is a copy of the others and updating one element will update all the remaining ones."""
xidx = xyidx[0] ref = False
if not options.reference is None: ref = True
rdx = int(options.reference)
for line in fid:
data = line.split()
for item, yidx in enumerate(xyidx[1:]): xx[item].append(float(data[xidx])) yy[item].append(float(data[yidx]))
fid.close()
xout += xx yout += yy
ylegend += yname
# call the plot |
function |
|
plot(outfile, |
xout, yout, xname, ylegend, |
|
style |
= |
options.style, |
legend |
= |
options.legend, |
names |
= |
options.names, |
ylabel |
= |
options.ylabel, |
grid |
= |
options.grid, |
position |
= |
options.position) |
if name == ’ main ’:
parse results()
The standard library OptionParser provides the user with Unix-like command line options. The function plot imports the Matplotlib library for creating the figure. A possible implementation of the function plot is as follows.
482 22 Visualization Matters
from matplotlib import |
pyplot |
def plot(output, x, y, |
xname, yname, style=’colors’, |
legend=True, |
grid=False, |
ylabel=None, |
position=’lower right’): |
colors = [’b’, ’r’, ’g’, ’c’, ’m’, ’y’] black = [’k-’, ’k--’, ’k:’, ’k-.’, ’k,’]
fig = pyplot.figure() pyplot.hold(True)
if style in (’black’, ’b’): s = black
else: # default is "colors" or "c" s = colors
for item in xrange(len(y)): pyplot.plot(x[item], y[item], \
s[item % len(s)], label=yname[item])
if legend:
if position.isdigit(): position = int(position)
pyplot.legend(loc=position)
pyplot.xlabel(xname) if not ylabel is None:
pyplot.ylabel(ylabel)
pyplot.grid(grid)
# plot figure and save to file pyplot.savefig(output, format=’eps’) pyplot.show()
All plots provided in this book were obtained using the Python functions described in this example.
22.2.2Temperature Maps
Contour and temperature maps have proved to be an e ective solution for visualizing results of a variety of power system analyses. In [157, 158, 222, 223, 224, 303], 2D maps are used for visualizing a variety of results, such as power flows in transmission lines, locational marginal prices, available transfer capability, contingency analysis, etc. All the previous references are based on a proprietary software package [247] but, nowadays, scripting languages are mature enough for producing high quality temperature maps [197, 295].
From the implementation viewpoint, producing 2D maps is just a matter of assigning topological data (i.e., coordinates) to technical data (e.g., bus voltage magnitudes). This can be obtained using a one-line diagram editor

22.2 Result Visualization |
483 |
(e.g., PSAT leans on the Simulink editor [195]) or using graphical information systems (see Subsection 22.2.4).
Example 22.1 Temperature Map of the IEEE 14-Bus System
Figure 22.1 shows the voltage temperature map for the power flow solution of the IEEE 14-bus system. The procedure for obtaining the map is as follows.
1.Topological data have to be assigned to buses, lines and other devices that compose the system.
2.Once the power flow analysis is solved, bus coordinates and voltage magnitude values are collected as a set of triplets.
3.A map is created using the functions meshgrid and griddata from the libraries NumPy and Matplotlib, respectively. The function meshgrid creates a coordinate matrix of uniformly spaced points while griddata fits a surface of the form z = f (x, y) to the data in the non-uniformly spaced vectors of bus coordinates (x, y) and voltage magnitude values z.
4.The surface computed in the previous point is plotted using any of the 2D functions provided by the Matplotlib library. For example, Figure 22.1 is obtained using the function imshow.
Fig. 22.1 Voltage temperature map for the IEEE 14-bus system. Values in the legend are in pu