Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Учебники / 0841558_16EA1_federico_milano_power_system_modelling_and_scripting

.pdf
Скачиваний:
82
Добавлен:
08.06.2015
Размер:
6.72 Mб
Скачать

474

21 Data Formats

value = pair[1].strip() if value.startswith(’"’):

value = value[1:-1] elif value.startswith(’[’):

array = value[1:-1].split(’;’)

if math.search(value): # execute simple operations value = map(lambda x: eval(x), array)

else:

value = map(lambda x: float(x), array) elif double.search(value):

if math.search(value): # execute simple operations value = eval(value)

else:

value = float(value) elif value == ’True’:

value = True

elif value == ’False’: value == False

else:

value = int(value) kwargs[key] = value

index = kwargs.pop(’idx’, None) namex = kwargs.pop(’name’, None)

try:

system. dict [device].add(idx=index, name=namex, **kwargs) except KeyError:

print ’Device <%s> is will be skipped’ % device

return True

Chapter 22

Visualization Matters

This chapter discusses visualization matters related to power system analysis. In particular, the aspects covered in the chapter are the adequacy of graphical user interfaces versus the command line usage (Section 22.1) and available approaches for displaying results (Section 22.2). The latter describes standard two-dimensional plots (Subsection 22.2.1), temperature maps (Subsection 22.2.2), three-dimensional plots (Subsection 22.2.3), and the integration of graphical information systems into power system analysis software packages (Subsection 22.2.4).

22.1Graphical Interface vs. Command Line Approach

The current trend of proprietary operating systems and software applications is to mask the functioning of the software behind a Graphical User Interface (GUI). There is no doubt that intuitive GUIs simplify the learning process of the application, at least at the first approach. Furthermore, GUIs are certainly useful for didactic purposes. On the other hand, the weakness of any GUI is that the only allowed operations are those embedded in the GUI itself. Thus, GUIs reduce user freedom. This is a real issue for most scientific (i.e., number-crunching) applications.1

Opposite to GUIs is the command-line approach. The advantages of using a pure command-line approach for scientific applications are as follows.

1.The command-line approach allows e cient use on remote servers.

2.Batch programming is possible only with the command-line approach (see Script 22.1).

3.The size of the application can be very reduced if GUIs are taken apart.

4.GUIs are often operating system dependent. Thus, using a command line approach eases portability.

1It is important not to confuse GUIs with CAD/CAM applications and result visualization. The latter is discussed in the following section.

F. Milano: Power System Modelling and Scripting, Power Systems, pp. 475–488. springerlink.com c Springer-Verlag Berlin Heidelberg 2010

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)

480

22 Visualization Matters

interval = re.compile(r’\d+:\d+’) stepint = re.compile(r’\d+:\d+:\d+’) xname = ’’

ylegend = [] xout = [] yout = [] nval = 0

# parse argument list while len(args):

#data file name datafile = args.pop(0) listfile = args.pop(0)

#output file

outfile, ext = os.path.splitext(options.output) outfile += ’.eps’

# populate index vector xyidx = []

yname = [] while len(args):

if stepint.search(args[0]):

values = re.findall(r’\d+’, args.pop(0))

for item in range(int(values[0]), int(values[2]) + 1, \ int(values[1])):

xyidx.append(item) elif interval.search(args[0]):

values = re.findall(r’\d+’, args.pop(0))

for item in range(int(values[0]), int(values[1]) + 1): xyidx.append(item)

elif not args[0].isdigit(): break

else:

xyidx.append(int(args.pop(0)))

if len(xyidx) == 0: xyidx = [0, 1]

elif len(xyidx) == 1: xyidx.append(1)

# scan list file

fid = open(listfile, ’r’) for line in fid:

data = line.split(’,’)

if int(data[0].strip()) == xyidx[0]: xname = data[1].strip()

if int(data[0].strip()) in xyidx[1:]: yname.append(data[1].strip())

# order variable names according to command line order yidx = xyidx[1:]

ysorted = sorted(yidx)

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