1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412
|
<!--startcut ==============================================-->
<!-- *** BEGIN HTML header *** -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML><HEAD>
<title>Numerical Workbenches, part III LG #71</title>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
ALINK="#FF0000">
<!-- *** END HTML header *** -->
<CENTER>
<A HREF="http://www.linuxgazette.com/">
<IMG ALT="LINUX GAZETTE" SRC="../gx/lglogo.png"
WIDTH="600" HEIGHT="124" border="0"></A>
<BR>
<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="qubism.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="lg_toc71.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../lg_frontpage.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue71/spiel.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../lg_faq.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="lg_backpage71.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
<P>
</CENTER>
<!--endcut ============================================================-->
<H4 ALIGN="center">
"Linux Gazette...<I>making Linux just a little more fun!</I>"
</H4>
<P> <HR> <P>
<!--===================================================================-->
<center>
<H1><font color="maroon">Numerical Workbenches, part III</font></H1>
<H4>By <a href="mailto:cspiel@hammersmith-consulting.com">Christoph Spiel</a></H4>
</center>
<P> <HR> <P>
<!-- END header -->
<p>Parts I and II of this little series on numerical math workbenches on
GNU/Linux have covered rather dry subjects like matrix manipulations and <em>
for</em>-loops. This part brings more color to the screens as it turns to the
graphical capabilities of GNU/Octave, Scilab, and Tela. It will deviate from
the previous way of presenting the three applications, because the differences
of the graphical backends are far too big to allow for a uniform treatment
with only a few explanations on the differences.</p>
<p>The article starts with an introduction applicable to all programs. To give
the reader maximum benefit, all applications have to solve the same three real
life <a href="#problems">problems</a>. This simplifies the comparison despite
the differences of the implementations. In the last part, <a href="#octave">
Octave</a>, <a href="#scilab">Scilab</a>, and <a href="#tela">Tela</a> have to
tackle the given tasks.</p>
<h2><a name="introduction">Introduction</a></h2>
<dl>
<dt><strong><a name="item_Discrete_Data_Only">Discrete Data
Only</a></strong><br>
</dt>
<dd>As all three applications are designed to work with vectors and matrices,
their graphics backends only understand this kind of data. Doh! For the user
this means that the graph of a mathematical function like
<pre>
{ sin(x)/x for x <> 0
y := f(x) = {
{ 1 for x == 0
</pre>
<p>cannot be drawn from the above expression, but the function has to be
transformed into discrete pairs (<em>x(i)</em>, <em>y(i)</em>). This
transformation is called sampling. To sample <em>f(x)</em>, we pick
values <em>x</em> where we are interested in <em>f(x)</em> and compute
<em>f</em> for the given <em>x</em>. Any reader who has followed the earlier
parts, will immediately recognize that this involves a vector operation.</p>
<pre>
### GNU/Octave code
</pre>
<pre>
function y = f(x)
if x == 0.0
y = 1.0;
else
y = sin(x) ./ x;
endif
endfunction
</pre>
<pre>
x = linspace(0.0, 4*pi, 50);
y = f(x);
</pre>
<p><em>linspace(start, end, n)</em> returns a vector from <em>start</em> to
<em>end</em>, whose <em>n</em> elements are evenly spaced. The
vectors <em>x</em> and <em>y</em> can be passed to an appropriate
plotting function.</p>
<p>If data already are in vectorized form, they can be displayed
immediately.</p>
</dd>
<dt><strong><a name="item_Complexity_at_Large">Complexity at
Large</a></strong><br>
</dt>
<dd>How do we actually display a graph? This question leads us to the
fundamental problem all applications run into when it comes to graphical
output of data: either complicated or many simple function calls! Let us first
consider the complexity for the user of a call to solve a system of linear
equations
<pre>
x = a \ b # Octave, Scilab
</pre>
<p>or</p>
<pre>
x = linsolve(a, b) // Tela
</pre>
<p>Even if we try hard to artificially complicate the calls (yet leaving them
useful), we hit the end of the road at</p>
<pre>
x = linsolve(a, b, "CompletePivoting", "DoIterativeRefinement")
</pre>
<p>This is, with the two additional parameters -- pivoting strategy and
iterative refinement of the solution -- the user completely controls <em>
linsolve()</em>. All other ``decisions'' can reasonably be taken by the
workbench itself, for example, what algorithm to use if matrix <em>a</em>
has a special form.</p>
<p>Contrast this with the 2d-graph of</p>
<pre>
x = [2.25, 2.27, 2.42, ...]
y = [0.363, 0.360, 0.337, ...]
</pre>
<p>What options can we think of?</p>
<ul>
<li>Draw isolated data points or connect data points with straight lines.</li>
<li>Which symbol to draw at each data point? A dot, star, circle, or asterisk?
What color should the data points be?</li>
<li>Which kind of line to draw between the data points? Continuous, dashed,
dotted, or dash-dotted? What line thickness and what color is the line?</li>
<li>Scale the plot to fit within the plotting window?</li>
<li>Draw coordinate axes? Linear or logarithmic <em>x</em> or <em>y</em> axis?
Both axes logarithmic?</li>
<li>Graduate or annotate the axes?</li>
<li>...</li>
</ul>
<p>Many more reasonable options are conceivable. The point is: we cannot
expect plotting to be as simple to use as is for example solving a system of
linear equations -- not because the applications are badly written, but
because the topic is inherently more complicated on the user's side. Hence,
nobody should be surprised if she ever needs 20 or more lines to define a
publication quality plot in Octave, Scilab, or Tela.</p>
</dd>
</dl>
<h2><a name="problems">Problems</a></h2>
<p>To make the competition interesting, I put up problems, which are not too
far away from the Real World(tm). Each of the three applications will have to
cope with three different types of plots:</p>
<ol>
<li><strong><a name="item_2D_Plot_of_Discrete_Data">2D Plot of Discrete
Data</a></strong><br>
<p>Display three sets of data (<a href="misc/spiel/l1.ascii">l1.ascii</a>, <a
href="misc/spiel/l2.ascii">l2.ascii</a>, <a href="misc/spiel/l3.ascii">
l3.ascii</a>) on a single page. The sets have a different number of data
points.</p>
<p>The data are stored as two columns, column 1 holds the <em>
x</em>-value, and column 2 the <em>y</em>-value:</p>
<pre>
0.2808 3.419E-07
0.3711 3.459E-07
0.4882 3.488E-07
...
</pre>
<p>The graph must show title, axes captions, and legend. The <em>x</em> and
<em>y</em> ranges are supplied by the user.</p>
</li>
<li><strong><a name="item_3D_Plot_of_a_Function">3D Plot of a
Function</a></strong><br>
Plot Rosenbrock's function (in two dimensions)
<pre>
f(u, v) = 100*(v - u^2)^2 + (1 - u)^2
</pre>
<p>as a 3d-surface in the parameter ranges -3 <= <em>
u</em> <= 3 and -2 <= <em>
v</em> <= 4.</p>
<p>Annotate the plot with title and axes captions.</p>
</li>
<li><strong><a name="item_Contour_Plot_of_a_Function">Contour Plot of a
Function</a></strong><br>
Plot function
<pre>
g(u, v) = exp(u) * (4*u^2 + 2*v^2 + 4*u*v + 2*v + 1)
</pre>
<p>with contours, this is, <em>f(u, v) = z</em> for given <em>z</em> in the
parameter ranges -4.5 <= <em>u</em> <= -0.5 and
-1 <= <em>v</em> <= 3.</p>
<p>The iso-lines are defined by a user-specified ``weight'' function.</p>
<pre>
( z - z_0 ) 3
z_iso = (z_1 - z_0) * ( --------- ) + z_0
( z_1 - z_0 )
</pre>
<p>where <em>z_0</em> and <em>z_1</em> are the minimum and maximum values of
<em>g(u, v)</em> in the plot's range.</p>
<p>Again, annotate the plot with title and axes captions.</p>
</li>
</ol>
<p>All graphics must be rendered for two devices,</p>
<ul>
<li>X11 terminal and</li>
<li>Postscript printer.</li>
</ul>
<h2><a name="octave">Octave</a></h2>
<p>You know Gnuplot? Then learning to use GNU/Octave's plot functions will be
a piece of cake. All you need to do is precede the Gnuplot commands with a
``<code>g</code>'' to reach at the Octave equivalent. -- Oh, you haven't tried
Gnuplot yet? Then I will guide you through the examples. However, having a
Gnuplot manual (online or dead-tree edition) ready may be helpful.</p>
If you do not want to download Gnuplot's manual, you can use one of the <a
href=
"http://pi3.informatik.uni-mannheim.de/staff/mitarbeiter/westmann/gnuplot.html">
publicly accessible versions</a>.
<h3><a name="octave: 2d discrete data plot">Octave: 2D Discrete Data
Plot</a></h3>
<p>For an easier discussion, I have split the code into blocks. Each block
gathers commands that belong together. The blocks are labeled with numbers in
square brackets, to allow for referencing them in the text.</p>
<pre>
### [1] Read data set_i into N_i-times-2 matrices
set1 = load("l1.ascii");
set2 = load("l2.ascii");
set3 = load("l3.ascii");
</pre>
<pre>
### [2] Reset Gnuplot
graw("reset;");
clearplot;
</pre>
<pre>
### [3] Define decorations and plot area
gset title "Comparison of sets L1, L2, and L3";
gset xlabel "Temperature / K";
gset ylabel "Voltage / V";
gset key top left;
gset xrange [0 : 100];
gset yrange [8e-8 : 2e-6];
</pre>
<pre>
### [4] Plot data
hold on;
gplot set1 title "Set L1" with points;
gplot set2 title "Set L2" with points;
gplot set3 title "Set L3" with points;
hold off;
</pre>
<pre>
### [5] Switch to PostScript output and plot into file
gset terminal push;
gset terminal postscript;
gset output "oct1.eps";
replot;
gset terminal pop;
gset output;
</pre>
<p><img height="450" alt=
"[Graphics: The Gnuplot window that has been opened by Octave's graphics commands shows the three data sets. The data points are drawn with blue, green, and red markers. The markers themselves have different shape. The plot has a title. Both axes show the annotations as defined by the gset-commands.]"
src="misc/spiel/oct1.png" width="600"> The output to the Postscript terminal,
block [6], produced a <a href="misc/spiel/oct1.eps">printable version
(eps)</a> of the graphics.</p>
<p>Block [1] should be clear from the previous articles. The first
interaction with Gnuplot happens in [2], where Gnuplot is reset to a known
state and the X11-plot window gets cleared. A known state is helpful when
still experimenting with Gnuplot's options. In our case reseting is
unnecessary, but it does not hurt.</p>
<p>The block of <code>gset</code> commands, [3] is self explaining except</p>
<pre>
gset key top left
</pre>
<p>which means: ``put the legend (or key) inside the plotting area at the
north-west corner''. <code>xrange</code> and <code>yrange</code> with their
special interval syntax set the width and height of the plot range.</p>
<p>Now, the actual data can be rendered into the plot window [4]. Because the
data sets have different sizes, they cannot be gathered in a single matrix.
Hence, each data set must be plotted by itself, and Gnuplot must be told --
with <code>hold on</code> -- that it should collect all <code>
gplot</code> commands until the last plot of the set is completed and
<code>hold off</code> is called. The calls to <em>gplot</em> essentially
contain the data matrix</p>
<pre>
gplot set1
</pre>
<p>The title, which shows up in the plot's legend, is assigned in the call to
<code>gplot</code>, too.</p>
<p>Block [5] is specific to the way Gnuplot works. For each plot it uses
a <em>terminal</em> and an <em>output</em> file (remember that in UN*X
everything is a file, as for example is the console). When Gnuplot is running
under X, the terminal type defaults to X11 and output file defaults to
Gnuplot's X11-graphic window. Both, <em>terminal</em> and <em>
output</em> file can be changed independently with <code>gset</code>
commands. Thus, to get the same graphics in a different format, we switch from
the current terminal to Postscript, and put an ordinary file's name at the
output. Function <code>replot</code> replays all plot commands for us, we
do not have to write them again. After that the terminal and output settings
are undone, which is optional, but helpful if the user wants to twiddle some
more <code>gset</code>'s and repeatedly check their influence on the graph's
appearance.</p>
<h3><a name="octave: 3d function plot">Octave: 3D Function Plot</a></h3>
<pre>
### [1] Define function
function z = f(u, v)
## truncated Rosenbrock function
z = 100.0*(v - u.^2).^2 + (1.0 - u).^2;
zv = z(:);
zv(find(zv > 100.0)) = 100.0;
z = reshape(zv, size(z));
endfunction
</pre>
<pre>
### [2] Sample function f()
x = linspace(-3, 3, 40);
y = linspace(-2, 4, 40);
[xx, yy] = meshgrid(x, y);
z_splot = splice_mat(xx, yy, f(xx, yy));
</pre>
<pre>
### [3] Reset Gnuplot
graw("reset;");
clearplot;
</pre>
<pre>
### [4] Define decorations and viewing direction
gset data style line;
gset title "Rosenbrock Function";
gset xlabel "u";
gset ylabel "v";
gset view 30, 160;
gset hidden;
gset nokey
gset parametric;
</pre>
<pre>
### [5] Plot
gsplot z_splot;
</pre>
<pre>
### [6] Switch to PostScript output and plot into file
gset terminal push;
gset terminal postscript;
gset output "oct2.eps";
replot;
gset terminal pop;
gset output;
gset noparametric;
</pre>
<pre>
system("gzip --best --force oct2.eps");
</pre>
<p><img height="450" alt=
"[Graphics: The Gnuplot window shows a red-mesh that is 'deformed' according to function f(u, v). The whole plot looks like the imprint of a boomerang.]"
src="misc/spiel/oct2.png" width="600"> A <a href="misc/spiel/oct2.eps.gz">
printer-ready version</a> (eps.gz) is available, too.</p>
<p>Again the first block, [1], should be easy to understand for anyone who has
read Part 1 and 2 of this series for it only uses known functions. In
contrast, [2] introduces two new functions. Out friend <em>linspace()</em>
quickly generates two vectors which will define where <em>f(u, v)</em> will be
evaluated: from vectors <em>x</em> and <em>y</em>, a grid is constructed,
this is, two matrices <em>xx</em> and <em>yy</em>, where each pair of
matrix elements <em>(xx(i, j), yy(i, j))</em>,
1 <= <em>i</em>, <em>j</em> <= 40, define a (grid-)
point at which function <em>z = f(u, v)</em> will be evaluated.
The matrix of all <em>z</em>-values at the grid points then simply is <code>zz
= f(xx, yy)</code>. However, we are not done at this point, because Octave
requires to pass a specially formatted matrix to the 3d-plot
function <em>gsplot</em>.</p>
<p>The user-defined function <a href="misc/spiel/splice_mat.m">
splice_mat()</a> does exactly the needed operation: collect the grid data <em>
xx</em> and <em>yy</em> along with the <em>z</em>-values in matrix <em>
z_plot</em>. Matrix <em>z_plot</em> can be handed over to <em>gsplot</em>
without further ado (given Gnuplot is in parametric mode. (we will be in
parametric mode and for the given kind of problem parametric mode is the only
way to go (and I don't want to introduce another level of parenthesis
(really!))))</p>
<p>Block [4], a collection of <code>gset</code>s, looks almost familiar.
Some new settings are</p>
<ul>
<li><strong><a name="item_gset_data_style_line">gset data style
line</a></strong><br>
Join adjacent mesh-points with (by default: red) lines.</li>
<li><strong><a name="item_gset_view_x_angle%2C_z_angle">gset view x_angle,
z_angle</a></strong><br>
Rotate the view point around the <em>x</em>-axis by <em>x_angle</em> degrees,
then rotate around the new <em>z</em>-axis by <em>z_angle</em> degrees.</li>
<li><strong><a name="item_gset_hidden">gset hidden</a></strong><br>
Suppress invisible mesh lines. The back side of the mesh is drawn differently
(green in the X11-window and with dashed black lines in the
Postscript terminal).</li>
<li><strong><a name="item_gset_nokey">gset nokey</a></strong><br>
Suppress any legend.</li>
<li><strong><a name="item_gset_parametric">gset parametric</a></strong><br>
See GNU/Octave's documentation. (<code>help -i gsplot</code> from Octave, or
<code>info octave --node='Three-Dimensional Plotting'</code> from the
shell.)</li>
</ul>
<p>After so much preparation, the actual plot command, <code>gsplot
z_splot</code> in [5] looks trivial.</p>
<p>The Postscript block [6] is similar to [5] in Section <a href=
"#octave: 2d discrete data plot">``Octave: 2d discrete data plot''</a>. The
only additional job [6] does is gzipping the eps-file. In general <em>
system(``shell-commands'')</em> executes <em>shell-commands</em> in a
sub-shell. Obviously, this is extremely useful when interacting with an
external application, like gzip(1).</p>
<h3><a name="octave: contour function plot">Octave: Contour Function
Plot</a></h3>
<pre>
### [1] Define function
function z = g(u, v)
z = exp(u) .* (4.0*u.^2 + 2.0*v.^2 + 4.0*u.*v + 2.0*v + 1.0);
endfunction
</pre>
<pre>
### [2] Define weight function for iso-line distances
function y = pow_weight(x, n)
## Map interval X onto itself, weight with N-th power.
d = max(x) - min(x);
y = d*((x - min(x))/d).^n + min(x);
endfunction
</pre>
<pre>
### [3] Sample function g()
x = linspace(-4.5, -0.5, 40);
y = linspace(-1.0, 3.0, 40);
[xx, yy] = meshgrid(x, y);
zz = g(xx, yy);
z_splot = splice_mat(xx, yy, zz);
</pre>
<pre>
### [4] Compute iso-line distances
iso_levels = pow_weight(linspace(min(min(zz))*1.01, ...
max(max(zz))*0.99, 12), 3.0);
il_str = sprintf("%f,", iso_levels);
il_str = il_str(1 : length(il_str)-1); # remove last ","
</pre>
<pre>
### [5] Reset Gnuplot
graw("reset;");
clearplot;
</pre>
<pre>
### [6] Define decorations and viewing direction
gset data style line;
gset title "Contour Plot of g(u, v)";
gset xlabel "u";
gset ylabel "v";
gset contour base;
gset nosurface;
gset view 0, 0;
eval(sprintf("gset cntrparam levels discrete %s", il_str));
gset parametric;
</pre>
<pre>
### [7] Plot
gsplot z_splot;
</pre>
<pre>
### [8] Switch to PostScript output and plot into file
gset terminal push;
gset terminal postscript;
gset output "oct3.eps";
replot;
gset terminal pop;
gset output;
gset noparametric;
</pre>
<p><img height="450" alt=
"[Graphics: The Gnuplot window shows 12 iso-lines each with a different color. The plot exhibits a saddle point of g(u, v) in the right third of the image.]"
src="misc/spiel/oct3.png" width="600"> A <a href="misc/spiel/oct3.eps">
printable version (eps)</a> is available, too.</p>
<p>After working through the 2d discrete and the 3d function plot examples,
the top three blocks [1-3] of the contour function script should not
raise many questions. In block [4] however, I have to prepare a trick,
which I must play at the end of block [6]. The job is to plot contour
lines with a user-defined function. The values of this function and therefore
the positions of the iso-lines are not known in advance.</p>
<p>Gnuplot offers several ways to define iso-lines, for example, automatic
computation of a given number of (linearly spaced) contours or defining a
minimum and a maximum contour value with a fixed increment between two
adjacent contours. Our problem requires a more general solution because the
iso-lines are not equally spaced along the <em>z</em>-axis. For completely
arbitrary iso-line values, as the third way if specifying contour lines,
Gnuplot has the following <code>gset</code> command</p>
<pre>
gset cntrparam discrete z1, z2, ..., zN
</pre>
<p>where <em>z1</em>, <em>z2</em>, ..., <em>zN</em> are the <em>z</em>-values
of the iso-lines given as <em>floating point literals</em>. Thus,</p>
<pre>
gset cntrparam discrete 0.2, 0.4, 0.8
</pre>
<p>is a perfect call, whereas</p>
<pre>
z1 = 0.2
z2 = 0.4
z3 = 0.8
gset cntrparam discrete z1, z2, z3
</pre>
<p>is nothing but a syntax error as would be</p>
<pre>
gset cntrparam discrete iso_levels
</pre>
<p>Remember, <code>gset</code> needs floating point literals!</p>
<p>We are stuck unless we apply a bit of magic. If we present a complete
<code>gset</code> line to Octave, one where the values of vector <em>
iso_levels</em> are ``interpolated'' into (Perl programmers do this all day
long), the race is won. Here is how the trick is played:</p>
<pre>
# Convert iso_levels to comma-separated string. Octave reuses
# the format specifier list if there are more items to print than
# there are format specifiers. Don't try this with C's printf :-)
il_string = sprintf("%f,", iso_levels)
</pre>
<pre>
# Remove comma past last contour value in the string.
il_string = il_string(1 : length(il_string)-1)
</pre>
<pre>
# Play interpolation trick a second time
gset_string = sprintf("gset cntrparam levels discrete %s", il_string);
</pre>
<pre>
# Execute the command which is stored in the variable gset_string
eval(gset_string);
</pre>
<p>For readers who do not like abstract descriptions, this is a transcript of
a session (where long lines have been edited to fit):</p>
<pre>
octave:10> il_string = sprintf("%f,", iso_levels)
il_string = 0.583444,0.592029,0.652120,0.815224,1.132847,1.656497, \
2.437679,3.527900,4.978667,6.841486,9.167864,12.009307,
octave:11> il_string = il_string(1 : length(il_string)-1)
il_string = 0.583444,0.592029,0.652120,0.815224,1.132847,1.656497, \
2.437679,3.527900,4.978667,6.841486,9.167864,12.009307
octave:12> gset_string = sprintf("gset cntrparam levels discrete %s", \
il_string)
gset_string = gset cntrparam levels discrete 0.583444,0.592029, \
0.652120,0.815224,1.132847,1.656497,2.437679,3.527900, \
4.978667,6.841486,9.167864,12.009307
</pre>
<p>In the script, no temporary variable <em>gset_string</em> has been
introduced, but <em>sprintf()</em> sends its output directly to <em>
eval()</em>.</p>
<p>Block [6]: Gnuplot does not excel in plotting contours. In fact the
GNuplot user-manual suggests not to use it directly. Anyhow, we proceed,
because the out approach is easier to understand. The following three <code>
gset</code>s switch Gnuplot into contour-mode:</p>
<pre>
gset contour base # draw contours in the xy-plane
gset nosurface # do not draw the surface's mesh
gset view 0, 0 # view the xy-plane from above
</pre>
<p>Blocks [7] and [8] closely resemble those we have already seen in
Section <a href="#octave: 2d discrete data plot">``Octave: 2D Discrete Data
Plot''</a> and <a href="#octave: 3d function plot">``Octave: 3D Function
Plot''</a>.</p>
<p>More demo plots of Gnuplot can be found at <a href=
"http://www.gnuplot.org/gnuplot/gpdocs/all2.htm">
http://www.gnuplot.org/gnuplot/gpdocs/all2.htm</a></p>
<h2><a name="scilab">Scilab</a></h2>
<p>And now for a rather different approach ...</p>
<p>Scilab goes a different way to cope with the complexity, which we have
discussed in Section <a href="#complexity at large">Complexity at Large</a>.
In contrary to Gnuplot, Scilab does not strictly separate plotting and
setting, but offers a plethora (buckle up, then try: <code>apropos
plot</code>) of different plot commands to produce different kinds of plots.
Furthermore, the plot functions themselves take many arguments that change the
plots' appearances. Some of the arguments are so cryptic that you almost
certainly will want to have the appropriate man-page within sight.</p>
<p>For the reader who wants to look at the on-line help, but does not have
Scilab installed, the <a href=
"http://www.num.uni-sb.de/~ehrhardt/Ue_PraMa/scilab/doc/html/manual/docu023.html">
Scilab manual</a> is available online.</p>
<h3><a name="scilab: 2d discrete data plot">Scilab: 2D Discrete Data
Plot</a></h3>
<pre>
// [1] Read data set_i into N_i-times-2 matrices
set1 = read("l1.ascii", -1, 2);
set2 = read("l2.ascii", -1, 2);
set3 = read("l3.ascii", -1, 2);
</pre>
<pre>
// [2] Clear plot window's contents
xbasc();
</pre>
<pre>
// [3] Plot data; 1st plot command defines plot area
plot2d(set1(:, 1), set1(:, 2), -1, "011", ..
rect = [0, 8e-8, 100, 2e-6]);
plot2d(set2(:, 1), set2(:, 2), -2, "000");
plot2d(set3(:, 1), set3(:, 2), -3, "000");
</pre>
<pre>
// [4] Define decorations
xtitle(["Comparison of sets", "L1, L2, and L3"], ..
"Temperature / K", "Voltage / V");
legends(["Set L1 ", "Set L2 ", "Set L3 "], [-1, -2, -3], 2);
</pre>
<pre>
// [5] Save plot window's contents to file; convert file to PostScript
xbasimp(0, "sci1.xps");
unix("scilab -save_p sci1.xps.0 Postscript");
</pre>
<p><img height="447" alt=
"[Graphics: Please see the image caption of '2D Discrete Data Plot' in the Octave section.]"
src="misc/spiel/sci1.png" width="600"> The <a href="misc/spiel/sci1.eps">
Encapsulated Postscript output</a> is available, too.</p>
<p>Block [1] reads the data from disk-files into matrices.</p>
<p>Block [2] clears the graphics window (if it exists). Even more
important, <em>xbasc()</em> deletes all graphics commands that have been
recorded for the window. The mnemonic for <em>xbasc()</em> is x-bas-c for
<strong>x</strong>11-function, <strong>bas</strong>ic level, <strong>
c</strong>lear.</p>
<p>Tip: When playing with Scilab's plot functions, preceding the plot function
call with a clear command often saves keystrokes</p>
<pre>
xbasc(); plot2d(...);
</pre>
<p>in one line can be recalled for editing with a single C-p and replayed with
a single hit of the return-key.</p>
<p>In Block [3] the enigma raises its head! What in the world does</p>
<pre>
plot2d(set1(:, 1), // vector of x-values
set1(:, 2), // vector of y-values
-1, // style index
"011", // decoration control
rect = [0, 8e-8, 100, 2e-6]); // plot dimensions
</pre>
<p>do? I have added a comment for each argument, yet, to what does a ``style
index'' of -1 refer to? A badly dressed hacker? And what does the string in
``decoration control'' mean?</p>
<dl>
<dt><strong><a name="item_Style_index">Style index</a></strong><br>
</dt>
<dd>controls the kind of marker to draw for each data point or the color of
the line that joins the data points. A positive value <em>i</em> means:
draw a line with color <em>i</em>, a negative value means: use marker
type <em>abs(i)</em>. Note that <em>plot2d()</em> draws either markers or
lines, never both. If markers and lines are required for the same data set,
two plots with different style indices are necessary.</dd>
<dt><strong><a name="item_Decoration_control">Decoration
control</a></strong><br>
</dt>
<dd>always is a string of length 3. Each character of the string controls
a certain aspect of the plot's decorations.
<dl>
<dt><strong><a name="item_Character_1">Character 1</a></strong><br>
</dt>
<dd>Toggle display of the plot caption. '<code>0</code>' is no caption,
'<code>1</code>' tells Scilab to display a caption.</dd>
<dt><strong><a name="item_Character_2">Character 2</a></strong><br>
</dt>
<dd>Control how the size of the plot is computed. Valid characters range from
'<code>0</code>' to '<code>8</code>'. Please see <em>plot2d()</em>
documentation for details.
<p>Here, we use '<code>1</code>' for the first plot and '<code>0</code>' for
all others. '<code>1</code>' lets the user explicitely specify the plot range
in the <code>rect</code> argument to <em>plot2d()</em>. If <em>
plot2d()</em> is called with '<code>0</code>', the size of a previous plot is
used and no size computation is done.</p>
</dd>
<dt><strong><a name="item_Character_3">Character 3</a></strong><br>
</dt>
<dd>Set the type of axes drawn around the plot. The user can choose from six
different values. We choose '<code>1</code>' for the first plot, which gives
axes on the bottom and the left hand side. The following plots use
'<code>0</code>', which means nothing is drawn around the plot.</dd>
</dl>
</dd>
</dl>
<p>Gee, that is quite a mouthful! Block [4] will give us some rest.</p>
<pre>
xtitle([title_line1; title_line2; ...], x_label, y_label)
</pre>
<p>Puts a possibly multi-line title into an existing plot and optionally
decorates the <em>x</em> and <em>y</em>-axis with labels.</p>
<pre>
legends([legend_1, legend_2, ...], [style_1, style_2, ...], position)
</pre>
<p>Places a legend in a plot where the position is given by <em>position</em>.
<em>position = 1</em> refers to the north east corner. The remaining corners
are enumerated counter-clockwise, this is, <em>position = 2</em> will put the
legend in the north west corner. The <em>style_i</em> parameters refer to the
same numbers that we have used as style indices in the <em>plot2d()</em>
calls. They determine which kind of marker or line is drawn right next to the
legend's text. The text is given by <em>legend_i</em>.</p>
<p>Finally, Block [5] converts the data in the graphics window to a
Postscript file.</p>
<pre>
xbasimp(0, "sci1.xps")
</pre>
<p>Replays all graphics commands for window 0 (our only graphics window)
into <em>sci1.xps</em>. The function's name has nothing to do with a
X11-daemon named ``bas'', but has its stem from <strong>x</strong>11 and
<strong>bas</strong>ic level as <em>xbasc()</em>. The ``<strong>imp</strong>''
comes from the French word ``imprimer'', which means ``to print''. From which
language does ``fsck'' come from? N vcls, I guess.</p>
<p>File <em>sci1.xps</em> almost contains valid Postscript, but not
quite. The contents must be processed by Scilab</p>
<pre>
scilab -save_p sci1.xps.0 Postscript
</pre>
<p>adding the correct Postscript header and repositioning the graphics on the
page. The external Scilab is called by the <em>
unix(``shell-commands'')</em> function.</p>
<h3><a name="scilab: 3d function plot">Scilab: 3D Function Plot</a></h3>
<pre>
// [1] Define function
function z = f(u, v)
// truncated Rosenbrock function
z = 100.0*(v - u.^2).^2 + (1.0 - u).^2
z(find(z > 100)) = 100;
endfunction
</pre>
<pre>
// [2] Define sampling grid for f()
x = linspace(-3, 3, 40);
y = linspace(-2, 4, 40);
</pre>
<pre>
// [3] Clear plot window's contents
xbasc();
</pre>
<pre>
// [4] Plot
fplot3d(x, y, f, 65, 1.5);
</pre>
<pre>
// [5] Define decoration
xtitle("Rosenbrock Function", "u", "v");
</pre>
<pre>
// [6] Save plot window's contents to file; convert file to PostScript
xbasimp(0, "sci2.xps");
unix("scilab -save_p sci2.xps.0 Postscript; " ..
+ "gzip --best --force sci2.eps");
</pre>
<p><img height="447" alt=
"[Graphics: Please see the image caption of '3D Function Plot' in the Octave section.]"
src="misc/spiel/sci2.png" width="600"> Here is the gzipped <a href=
"misc/spiel/sci2.eps.gz">Encapsulated Postscript version</a> (eps.gz) of the
graphics.</p>
<p>After so much new stuff in Section <a href="#scilab: 2d discrete data
plot">Scilab: 2D Discrete Data Plot</a> the only unknown here hides in
Block [4]:</p>
<pre>
fplot3d(x_vector, y_vector, function_of_x_and_y, alpha, theta)
</pre>
<p>The vectors <em>x_vector</em> and <em>y_vector</em> define the grid on
which <em>function_of_x_and_y</em> is evaluated. Comparing <em>fplot3d()</em>
with Octave's <em>gsplot</em> we notice, that Scilab generates the grid for
us. Function <em>fplot3d()</em> is a convenience function, built on top
of</p>
<pre>
plot3d(x_vector, y_vector, z_matrix, alpha, theta)
</pre>
<p>which resembles <em>gsplot</em> (and Tela's <em>mesh()</em>).</p>
<p>The parameters <em>theta</em> and <em>alpha</em>, define the elevation of
the view point and the rotation around the <em>z</em>-axis respectively.</p>
<h3><a name="scilab: contour function plot">Scilab: Contour Function
Plot</a></h3>
<pre>
// [1] Define function
function z = g(u, v)
z = exp(u) .* (4.0*u.^2 + 2.0*v.^2 + 4.0*u.*v + 2.0*v + 1.0)
endfunction
</pre>
<pre>
// [2] Define weight function for iso-line distances
function y = pow_weight(x, n)
// Map interval X onto itself, weight with N-th power.
d = max(x) - min(x)
y = d*((x - min(x))/d).^n + min(x)
endfunction
</pre>
<pre>
// [3] Define sampling grid for g()
x = linspace(-4.5, -0.5, 40);
y = linspace(-1.0, 3.0, 40);
</pre>
<pre>
// [4] Evaluate g() at points defined by X and Y
z = eval3d(g, x, y);
</pre>
<pre>
// [5] Compute iso-line distances
iso_levels = pow_weight(linspace(min(z)*1.01, max(z)*0.99, 12), 3.0);
</pre>
<pre>
// [6] Clear plot window's contents
xbasc();
</pre>
<pre>
// [7] Set format of iso-line annotation and plot
xset("fpf", "%.2f");
contour2d(x, y, z, iso_levels);
</pre>
<pre>
// [8] Define decoration
xtitle("Contour Plot of g(u, v)", "u", "v");
</pre>
<pre>
// [9] Save plot window's contents to file; convert file to PostScript
xbasimp(0, "sci3.xps");
unix("scilab -save_p sci3.xps.0 Postscript");
</pre>
<p><img height="447" alt=
"[Graphics: Please see the image caption of 'Contour Function Plot' in the Octave section for the image's description.]"
src="misc/spiel/sci3.png" width="600"> The output is available as <a href=
"misc/spiel/sci3.eps">printer-ready version</a> (eps), too.</p>
<p>Remember the difficulties we had with the user-defined iso-lines in
Octave/Gnuplot? The problem can be solved in Scilab without any tricks, magic,
or bribery. As with <em>plot3d()</em>, Scilab defines a convenience
function</p>
<pre>
fcontour2d(x_vector, y_vector, function_of_x_and_y, levels)
</pre>
<p>as a wrapper around</p>
<pre>
contour2d(x_vector, y_vector, z_matrix, levels)
</pre>
<p>However, as we must know the maximum and minimum value of <em>g(u, v)</em>
on the grid, <em>fcontour2d()</em> would not save us anything. Thus, Block [4]
computes <em>g(u, v)</em> on the grid defined by <em>x</em> and <em>
y</em>:</p>
<pre>
z = eval3d(g, x, y)
</pre>
<p>In Block [7], we use <em>z</em> and <em>iso_levels</em> from
Block [5]. The <em>xset()</em> call sets the <strong>f</strong>loating
<strong>p</strong>oint <strong>f</strong>ormat (``fpf'') to
``<code>%.2f</code>'', which is a C-printf format specifier that forces all
contour line numbers to have two digits after the decimal point.</p>
<p>All other blocks only use functions already discussed in the other
plots.</p>
<p>More demo plots of Scilab are found at <a href=
"http://www-rocq.inria.fr/scilab/doc/demos_html/node183.html">INRIA's Scilab
site</a>.</p>
<p>Scilab has much more to offer than the functions we have seen right above.
For example, it supplies</p>
<ul>
<li>Low-level functions to draw points, lines, polygons, etc.</li>
<li>
<p>Surface facets which are the building blocks for 3d-environments. (See for
example Enrico Segre's amazing <a href=
"http://www.polito.it/~segre/scigallery.html">Scigallery</a>)</p>
</li>
<li>High-level GUI-interface for rapid development of tailor-made Scilab
applications.</li>
<li>Feedback functions that allow passing back information from any graphics
window to Scilab.</li>
</ul>
<h2><a name="tela">Tela</a></h2>
<p>In the sections on <a href="#octave">Octave</a> and <a href="#scilab">
Scilab</a>, we have seen that both applications save auxiliary ``state'' of
the plot window. Gnuplot does so to the max: <code>gplot</code> or <code>
gsplot</code> have almost no parameters. The state is controlled by <code>
gset</code> commands. Scilab stores some state of the plot window as, for
example, the legend and title.</p>
<p>Tela uses the external application PlotMTV to display graphs. With PlotMTV,
Tela is located on the other side of the spectrum: its plots have no state,
and all information about the plot has to go into the call to the actual
plotting function. The advantage of Tela's approach is that multiple plots do
not interfere (unless we force them to do so by calling <code>hold(on)</code>
or <code>hold(off)</code> as we will see soon). The downside is that the calls
to plotting functions can get rather long.</p>
<p>As has been in the discussions of the other plotting applications, it is
helpful to have a PlotMTV manual within reach.</p>
<h3><a name="tela: 2d discrete data plot">Tela: 2D Discrete Data Plot</a></h3>
<pre>
// [1] Read data set_i into N_i-times-2 matrices
set1 = import1("l1.ascii");
set2 = import1("l2.ascii");
set3 = import1("l3.ascii");
</pre>
<pre>
// [2] Define plotting function
function do_plot(d1, d2, d3)
{
hold(on); // postpone actual plotting until hold(off)
</pre>
<pre>
// render set 1
plot(d1[:, 1], d1[:, 2],
"linestyle", 0,
"markertype", 2,
"linelabel", "Set L1",
// Define decorations
"toplabel", "Comparison of sets",
"subtitle", "L1, L2, and L3",
"xlabel", "Temperature / K",
"ylabel", "Voltage / V",
// Define plot area
"xmin", 0,
"xmax", 100,
"ymin", 8e-8,
"ymax", 2e-6);
// render set 2
plot(d2[:, 1], d2[:, 2],
"linestyle", 0,
"markertype", 3,
"linelabel", "Set L2");
// render set 3
plot(d3[:, 1], d3[:, 2],
"linestyle", 0,
"markertype", 4,
"linelabel", "Set L3");
</pre>
<pre>
hold(off); // plot!
};
</pre>
<pre>
// [3] Plot to X11 window
do_plot(set1, set2, set3);
</pre>
<pre>
// [4] Plot into a postscript file
plotopt("-o tela1.eps -printcmd 'cat' -noxplot -print");
do_plot(set1, set2, set3);
</pre>
<p>Hmm, this script looks differently! It does -- because I have to play
another trick that has to do with the statelessness plot functions. As Tela
``forgets'' the parameters after displaying graphics in an X11-window, I would
have to retype everything with output redirected to a Postscript file. Well,
code duplication is known to be the root of many (not all) evil. Thus, the
Tela plots are wrapped into a function. The further strategy is displaying the
plot in an X11 window, changing the output file and type, which is somewhat
analogous to Gnuplot, and then plotting again into an eps-file:</p>
<pre>
do_plot(...); // display plot in X11 window
plotopt("-o foo.eps -printcmd 'cat' -noxplot -print"); // redirect output
do_plot(...); // render plot in Encapsulated Postscript file foo.eps
</pre>
<p><img height="800" alt=
"[Graphics: Please see the image caption of '2D Discrete Data Plot' in the Octave section.]"
src="misc/spiel/tela1.png" width="600"> <a href="misc/spiel/tela1.eps">
Encapsulated Postscript version</a> of the graphics.</p>
<p>Function <em>do_plot</em> in Block [2] takes care of all output
by using function <em>plot()</em>. The general structure of Tela's <em>
plot()</em>, in fact all Tela plot functions, is first passing the mandatory
data arguments as vectors or matrices followed by optional key-value
strings.</p>
<pre>
plot(x_vector, y_vector // data
"option_key1", "option_value1", // option 1
"option_key2", "option_value2", // option 2
...
"option_keyN", "option_valueN"); // option N
</pre>
<p>Note that putting one key-value pair per line enhances the readability of
the whole call.</p>
<p>The key-value strings themselves are self-explaining. Non-obvious
associations like linestyle => 0 (= invisible line) or
markertype => 2 (= plus sign) must be looked up in the manual or
in a reference plot which shows all available line styles.</p>
<h3><a name="tela: 3d function plot">Tela: 3D Function Plot</a></h3>
<pre>
function v = linspace(a, b; n)
{
if (isdefined(n)) nn = n else nn = 100;
v = a + (0 : nn - 1) * (b - a) / (nn - 1)
};
</pre>
<pre>
// [1] Define function
function z = f(u, v)
{
// truncated Rosenbrock function
z = 100.0*(v - u^2)^2 + (1.0 - u)^2;
z[find(z > 100.0)] = 100.0;
};
</pre>
<pre>
// [2] Sample function f()
x = linspace(-3.0, 3.0, 40);
y = linspace(-2.0, 4.0, 40);
[xx, yy] = grid(x, y);
zz = f(xx, yy);
</pre>
<pre>
// [3] Define plot function
function do_plot(x, y, zz)
{
mesh(zz,
"xgrid", x,
"ygrid", y,
"toplabel", "Rosenbrock Function",
"xlabel", "u",
"ylabel", "v",
"hiddenline", "true",
"eyepos.z", 2.0)
};
</pre>
<pre>
// [4] Render plot into X11 window
do_plot(x, y, zz);
</pre>
<pre>
// [5] Plot into a postscript file
plotopt("-o tela2.eps -printcmd 'cat' -noxplot -print");
do_plot(x, y, zz);
system("gzip --best --force tela2.eps");
</pre>
<p><img height="800" alt=
"[Graphics: Please see the image caption of '3D Function Plot' in the Octave section.]"
src="misc/spiel/tela2.png" width="600"> An gzipped <a href=
"misc/spiel/tela2.eps.gz">Encapsulated Postscript version</a> (eps.gz) of the
plot is available, too.</p>
<p>Tela has no built in <em>linspace()</em> function, so I quickly define
one.</p>
<p>Block [2] resembles Block [2] in Section <a href="#octave: 3d
function plot">``Octave: 3D Function Plot''</a>, where Octave's <em>
meshgrid()</em> has been replaced by Tela's <em>grid()</em>.</p>
<p>The 3d-mesh plotting function <em>mesh()</em> takes a matrix of <em>
z</em>-values as its first argument; the grid-specification is given in the
options:</p>
<pre>
mesh(z_matrix,
"xgrid", x_vector,
"ygrid", y_vector);
</pre>
<p>Of course, the sizes of <em>z_matrix</em>, <em>x_vector</em>, and <em>
y_vector</em> must be compatible.</p>
<h3><a name="tela: contour function plot">Tela: Contour Function Plot</a></h3>
<pre>
function v = linspace(a, b; n)
{
if (isdefined(n)) nn = n else nn = 100;
v = a + (0 : nn - 1) * (b - a) / (nn - 1)
};
</pre>
<pre>
// [1] Define function
function z = g(u, v)
{
z = exp(u) * (4.0*u^2 + 2.0*v^2 + 4.0*u*v + 2.0*v + 1.0)
};
</pre>
<pre>
// [2] Define weight function for iso-line distances
function y = pow_weight(x, n)
{
// Map interval X onto itself, weight with N-th power.
d = max(x) - min(x);
y = d*((x - min(x))/d)^n + min(x)
};
</pre>
<pre>
// [3] Sample function f()
x = linspace(-4.5, -0.5, 40);
y = linspace(-1.0, 3.0, 40);
[xx, yy] = grid(x, y);
zz = g(xx, yy);
</pre>
<pre>
// [4] Compute iso-line distances
iso_levels = pow_weight(linspace(min(zz)*1.01, max(zz)*0.99, 12), 3.0);
il_str = sformat("``", iso_levels);
il_str = il_str[2 : length(il_str)];
</pre>
<pre>
// [5] Define plot function
function do_plot(x, y, zz, iso_levels_str)
{
contour(zz,
"xgrid", x,
"ygrid", y,
"toplabel", "Contour Plot of g(u, v)",
"xlabel", "u",
"ylabel", "v",
"contours", iso_levels_str)
};
</pre>
<pre>
// [6] Render plot into X11 window
do_plot(x, y, zz, il_str);
</pre>
<pre>
// [7] Plot into a postscript file
plotopt("-o tela3.eps -printcmd 'cat' -noxplot -print");
do_plot(x, y, zz, il_str);
</pre>
<p><img height="800" alt=
"[Graphics: Please see the image caption of 'Contour Function Plot' in the Octave section for the image's description.]"
src="misc/spiel/tela3.png" width="600"> Also available is an Encapsulated
Postscript <a href="misc/spiel/tela3.eps">printer version</a>.</p>
<p>Tela requires us to play a similar trick on PlotMTV as we had to when
convincing Octave to pass the contours' values to Gnuplot. However, the trick
in Block [4] is not as involved. Again, the first step is to compute the
vector <em>iso_levels</em>. Function <em>sformat()</em> works
analogously to Octave's <em>sprintf()</em>, though the vectors are differently
formatted as the transcript shows (<em>il_str</em> has been edited to fit the
line).</p>
<pre>
>il_str = sformat("``", iso_levels);
>il_str
"#(0.583444, 0.592029, 0.65212, 0.815224, 1.13285, 1.6565, \
2.43768, 3.5279, 4.97867, 6.84149, 9.16786, 12.0093)"
</pre>
<p>PlotMTV does understand a vector that is enclosed in parenthesis, but the
leading sharp-sign must go</p>
<pre>
il_str = il_str[2 : length(il_str)];
</pre>
<p>In this form, <em>il_string</em> can be passed as value to the option key
<code>contours</code> in function <em>contour()</em>.</p>
<p>More demo plots of PlotMTV can be found at <a href=
"http://csep1.phy.ornl.gov/cornell_proceedings/tutorials/Plotmtv/overview.html">
ORNL</a> and at <a href=
"http://www.hammersmith-consulting.com/plotmtv-us-g.html">HSC</a>.</p>
<p>By the way, PlotMTV suits perfectly as graphical backend for home grown
scripts and programs. The PlotMTV manual consistently helps the reader to
develop programmatic interfaces for her own applications.</p>
<h2><a name="closing comments on graphics">Closing Comments on
Graphics</a></h2>
<p>We have seen how to get publication ready data and function plots from
GNU/Octave, Scilab, and Tela. Sometimes the solutions have been intricate,
because of implementations' restrictions. However, all <a href="#problems">
problems</a> could be solved.</p>
<p>The effort in creating pleasantly looking graphs appears to be high and
almost independent of the chosen application.</p>
<!-- *** BEGIN bio *** -->
<SPACER TYPE="vertical" SIZE="30">
<P>
<H4><IMG ALIGN=BOTTOM ALT="" SRC="../gx/note.gif">Christoph Spiel</H4>
Chris runs an Open Source Software consulting company in Upper Bavaria/Germany.
<EM>Despite being trained as a physicist -- he holds a PhD in physics from Munich
University of Technology -- his main interests revolve around numerics,
heterogenous programming environments, and software engineering. He can be
reached at
<A HREF="mailto:cspiel@hammersmith-consulting.com">cspiel@hammersmith-consulting.com</A>.</EM>
<!-- *** END bio *** -->
<!-- *** BEGIN copyright *** -->
<P> <hr> <!-- P -->
<H5 ALIGN=center>
Copyright © 2001, Christoph Spiel.<BR>
Copying license <A HREF="../copying.html">http://www.linuxgazette.com/copying.html</A><BR>
Published in Issue 71 of <i>Linux Gazette</i>, October 2001</H5>
<!-- *** END copyright *** -->
<!--startcut ==========================================================-->
<HR><P>
<CENTER>
<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="qubism.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="lg_toc71.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../lg_frontpage.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue71/spiel.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../lg_faq.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="lg_backpage71.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
</CENTER>
</BODY></HTML>
<!--endcut ============================================================-->
|