Applied upstream as r3028 r3025 r3024
[PyX/mjg.git] / design / dtk / pyx.tex
blob327bb52656fdb712fe6e81dfb96362941f756781
1 \documentclass{scrartcl}
2 \usepackage[latin1]{inputenc}
3 \usepackage{ngerman,graphicx,listings,hyperref}
4 \lstloadlanguages{Python}
5 \lstset{language=Python,numbers=left,numberstyle=\tiny,numbersep=5pt}
6 \def\PyX{P\kern-.3em\lower.5ex\hbox{Y}\kern-.18em X}
7 \begin{document}
9 \title{Graphiken mit \PyX}
10 \author{Jörg Lehmann, André Wobst}
11 \maketitle
13 \tolerance=1500
15 \section{Einleitung}
17 Während sich \TeX/\LaTeX{} als De-facto-Standardlösung zum hochwertigen
18 Textsatz herausgebildet haben, ist die Situation bei Programmen zum
19 Erstellen von Abbildungen wesentlich unübersichtlicher. Verschiedenste,
20 zumeist auf bestimmte Anwendungsfälle zugeschnittene, Lösungen
21 konkurrieren miteinander. Ohne Anspruch auf Vollständigkeit seien hier
22 nur \textsc{Metapost}, das vorallem Stärken bei der Erzeugung geometrischer
23 Skizzen aufweist, \textsc{PSTricks}, das sich direkt in eine \LaTeX-Datei
24 einbinden lässt, sowie \textsc{Gnuplot} zur Erstellung von
25 Funktionsgraphen aufgeführt.
27 Ein Hauptkriterium bei der Auswahl einer geeigneten Lösung ist
28 sicherlich die Integration mit \TeX/\LaTeX. Schliesslich sollte die
29 Schriftart in der Abbildung möglichst mit derjenigen im Haupttext
30 übereinstimmen und natürlich sollte es möglich sein, von den \TeX s
31 Möglichkeiten des mathematischen Formelsatzes auch in Beschriftungen wie
32 gewohnt gebrauch zu machen. Die gerade genannten Programme erfüllen
33 diese Anforderung mehr oder minder, entweder bereits qua Design
34 (z.B. im Falle von \textsc{PSTricks}) oder durch ein integriertes (wie
35 bei \textsc{Metapost}) bzw. bei \textsc{Gnuplot} durch ein nachträglich aufgestülpbares
36 \TeX/\LaTeX-Interface.
38 Ist damit also alles in Butter? Leider nein, und der Hauptgrund liegt an
39 der mangelnden Universitaliät der eben beschriebenen Programme. Wer
40 schon einmal versucht hat das Resultat einer numerischen Berechnung
41 mittels \textsc{Metapost} oder \textsc{PSTricks} darzustellen, weiss wie
42 schwierig sich ein solches Unterfangen gestalten kann. Umgekehrt ist es
43 praktisch unmöglich, eine Schemazeichnung in \textsc{Gnuplot} zu
44 erstellen. Und wer kompliziertere programmatische Konstrukte zur
45 Generierung der Abbildung verwenden will, stösst bei allen drei Lösung
46 mehr oder minder schnell an seine Grenzen.
48 Neue Lösungen sind also gefragt und eine ebensolche, die
49 Graphikbibliothek \PyX{}, soll der Gegenstand dieses Artikels sein.
50 Implementiert in der mächtigen, aber gleichzeitig leicht erlernbaren,
51 Skriptsprache \textsc{Python}, stellt \PyX{} alle notwendigen
52 Konstrukte zur programmatischen Erzeugung von qualitativ hochwertigen
53 Abbildungen zur Verfügung. Aufbauend auf ein einer Abstraktion des
54 \textsc{PostScript}-Zeichenmodells und einer integrierten
55 \TeX/\LaTeX-Schnittstelle werden ausgefeilte Techniken zur
56 Realisierung typischer Graphikaufgaben von der schematischen
57 Darstellung bis zum Funktionsgraphen angeboten. Darüber hinausgehend
58 bietet die \TeX-Schnittstelle sogar Möglichkeiten im Textsatz die über
59 das bisher mit \TeX{} mögliche hinausgehen.
61 Während für das Arbeiten mit \PyX{} Grundkenntnisse in Python
62 empfehlenswert sind, zeigt die Erfahrung, dass es, eine gewisse
63 Programmiererfahrung vorausgesetzt, am Anfang ganz gut auch ohne
64 solche geht. Insbesondere sollten die in diesem Artikel vorgestellten
65 Programmbeispiele auch für Python-Neulinge verständlich sein.
67 \section{Installation}
69 \PyX{} setzt einen Python-Interpreter ab Version 2.1 voraus, der im
70 Handumdrehen installiert ist\footnote{Bei vielen Linux-Distributionen
71 sowie unter neueren Versionen von OS X gehört Python zur
72 Grundausstattung. Für Windows stehen unter \url{http://www.python.org}
73 fertige Installer zur Verfügung.}. \PyX{} kann nach dem Auspacken des
74 Archivs im Quellverzeichnis direkt verwendet werden; eine systemweite
75 Installation ist in der Grundkonfiguration mit einem einzigen Befehl
76 \verb|python setup.py install| erledigt. Darüber hinaus wird für die
77 Text-Ausgabe eine funktionsfähige \TeX-Installation vorausgesetzt, die
78 bei den Lesern der technischen Komödie sicher sowieso vorhanden sein
79 dürfte.
81 XXX bis hierher ist eigentlich alles ganz gut, aber jetzt
82 wird's zu theoretisch. Ich würde vorschlagen, an die Sache
83 viel anwendungsbezogener ranzugehen, sprich mit einem
84 Graphen anzufangen. Ob die Erklärung des PostScript-Pfadmodells
85 dann überhaupt noch notwendig ist, denke ich nicht.
87 \section{Grundlagen für Vektorgraphiken: Pfade}
91 Wie bereits erwähnt, abstrahiert \PyX{} das PostScript-Pfadsystem.
92 Dabei lassen sich Pfade aus einzelnen Pfadelementen zusammensetzen,
93 wobei gerade Linienstücke, Bezierkurven und Kreissegmente zur
94 Verfügung stehen. Zusätzlich lässt sich der aktuelle Punkt beim
95 Pfadaufbau neu setzen, so dass Pfade möglich sind, die aus mehreren,
96 nicht zusammenhängenden Pfadteilen bestehen. Natürlich können
97 (Teil-)Pfade auch geschlossen werden.
99 %Dabei werden Pfade als mathematische Objekte aufgefasst, also
100 %keine Linienbreite o.ä. besitzen.
102 \PyX{} ergänzt diese Grundfunktionalität zur Beschreibung von Pfaden
103 durch eine Vielzahl an geometrischen Operationen, die auf Pfaden
104 angewendet werden können. Beispielsweise lassen sich Pfade in
105 Teilstücke zerschneiden und neue Pfade aus bestehenden zusammensetzen.
106 Die Parametrisierung eines Pfades ist sowohl aufgrund der Bogenlänge
107 möglich wie auch mittels einer internen Parametrisierung auf der Basis
108 der im Pfad enthaltenen Pfadelemente. Weiterhin möglich ist die
109 Bestimmung von Schnittpunkten zwischen Pfaden und von geometrische
110 Eigenschaften entlang des Pfades, wie Tangenten und Krümmungsradien.
111 Für viele dieser Funktionen ist es notwendig, Pfade in sogenannte
112 Normpfade zu überführen, die nur noch aus Linien und Bezierkurven
113 bestehen und eine definierte, einstellbare Rechengenauigkeit besitzen.
114 Diese Konvertierung geschieht automatisch, sobald es für die
115 angeforderten Operationen notwendig ist, kann aber auch auch explizit
116 durchgeführt werden.
118 XXX warum nicht was zum Anfang malen, ist doch die Hauptaufgabe von
119 \PyX{}, oder?
121 In einem ersten Beispiel soll die Bogenlänge eines Einheitskreises
122 bestimmt werden. Dies erledigt folgendes kleine Python-Script:
123 \begin{quote}
124 \lstinputlisting{unitcircle.py}
125 \end{quote}
126 Abgespeichert als Datei \verb|unitcircle.py| kann es mit dem Befehl
127 \verb|python unitcircle.py| ausgeführt werden.
129 XXX im folgenden sind wir schon ganz schön tief drinnen, obwohl wir
130 noch gar nichts gezeigt haben. Der weniger geneigte Leser sagt hier
131 eventuell ade. Ist also vielleicht ein schlechtes Beispiel, oder?
133 In der ersten Zeile dieses Beispiels werden die \PyX{}-Module geladen.
134 Die zweite Zeile legt einen Einheitskreis an der Koordinatenposition
135 \verb|(0, 0)| mit dem Radius \verb|1| an. Das Koordinatensystem, das
136 \PyX{} verwendet, ist eine x-y-Ebene, in der die x-Achse horizontal
137 nach rechts verläuft und die y-Achse vertikal nach oben. Als Einheit
138 wird standardmäßig \verb|1 cm| verwendet.
140 In der dritten Zeile des Beispiels wird die Bogenlänge des Kreises
141 ausgegeben. Als Ausgabe erscheint: \begin{quote} \begin{verbatim}
142 (0.062832 t + 0.000000 u + 0.000000 v + 0.000000 w + 0.000000 x) m
143 \end{verbatim} \end{quote} Dieses etwas längliche Ergebnis mag
144 zunächst etwas überraschen. Andererseits zeigt es aber bereits eine
145 Grundfunktionalität des Einheitensystems von \PyX. Es gibt mehrere
146 Längenskalen, die unabhängig voneinander eingestellt werden können.
147 Die Komponenten \verb|t| bis \verb|x| stehen für \glqq{}true\grqq{}
148 (unskalierbar), \glqq{}user\grqq{} (Standardskala),
149 \glqq{}visual\grqq{} (für Abstände), \glqq{}width\grqq{} (für
150 Linienbreiten) und \glqq{}\TeX\grqq{} (für Textgrößen). Nachdem
151 ursprünglich gar keine Einheiten angegeben wurden, wurde in der
152 \glqq{}user\grqq-Längenskala im cm-Maßstab gearbeitet. Bei der
153 Berechnung der Bogenlänge mussten die Einheiten aufgelöst werden.
154 Folglich wird ein Ergebnis in der \glqq{}true\grqq-Längenskala in
155 Metern zurückgeliefert. Die anderen Komponenten werden zwar mit
156 ausgegeben, sind aber alle Null. Die recht komplizierte Darstellung
157 einer Länge als Zeichenkette braucht nicht weiter zu beunruhigen, denn
158 man kann mit diesen Einheiten ganz normal rechnen. Als Vorteil bleibt,
159 dass man beispielsweise die Größe einer fertigen Abbildung und die
160 verwendeten Liniendicken unabhängig voneinander variieren kann.
162 \section{Ausgabe von Pfaden: Dekoratoren}
164 Um Pfade auszugeben, müssen diese zunächst mit Zeichenattributen
165 versehen werden. Diese Aufgabe wird von sogenannten Dekoratoren
166 ausgeführt, die dekorierte Pfade erzeugen, die neben dem Pfad selbst
167 auch Attribute für das Zeichnen und Füllen des Pfades enthalten.
168 Zusätzlich können dekorierte Pfade Teile des ursprünglichen Pfades vom
169 Zeichnen ausschließen und Verziehrungen wie beispielsweise
170 Pfeilspitzen anbringen. Es ist möglich, mehrere Dekoratoren zusammen
171 oder sogar ineinander wirken zu lassen. Um das am Beispiel eines
172 Pfeiles zu demonstrieren, benötigt man noch eine Zeichenfläche, die
173 man nach Einfügen des dekorierten Pfades in eine PostScript oder PDF
174 Datei ausgeben kann. Der entsprechende Quelltext lautet:
176 XXX der Pfeil sieht ehrlicherweise nicht so toll aus (wegen der
177 gestrichelten Linie -> als erstes Beispiel nicht optimal (TeX-Fritzen
178 sind doch visuell empfindliche Zeitgenossen) Notfalls lassen wir
179 einfach die gestrichelte Linie weg.
181 \begin{quote}
182 \lstinputlisting{arrow.py}
183 \end{quote}
184 \begin{figure}[tp]
185 \centerline{\includegraphics[width=4cm]{arrow}}
186 \caption{Pfeil-Beispiel. Die Abbildung ist stark vergrößert, da das
187 Original sehr klein ist und auf die Weise die Details bequem sichtbar
188 werden.}
189 \label{fig:arrow}
190 \end{figure}
191 Die Ausgabe, die durch dieses Python-Script erzeugt wird, ist in
192 Abbildung~\ref{fig:arrow} zu sehen.
194 Zunächst werden in Zeile 2 und 3 eine Zeichenfläche \verb|c| und ein
195 Pfad \verb|p| angelegt. In Zeile 4 und 5 wird eine Liste aus zwei
196 Dekoratoren angelegt, die zum Zeichen und Füllen des Pfeils verwendet
197 werden sollen. Der entsprechende Pfeildekorator wird in Zeile 6 aus
198 dem bestehenden Pfeildekorator \verb|deco.earrow.large| erzeugt, also
199 eine abgewandelte Version des schon existierenden Dekorators gebildet.
201 In Zeile 7 kann nun die eigentliche Ausgabe stattfinden. Die
202 ausführliche Schreibweise wäre, für den Pfad selbst nochmal einen
203 \verb|stroked|-Dekorator anzuwenden und das Ganze mittels der
204 \verb|canvas|-Methode \verb|show| auszugeben. Das würde dann so
205 lauten: \verb|c.show(p, [deco.stoked([style.linestyle.dashed]), a])|.
206 Nachdem man Pfade aber sehr oft einfach nur Zeichen oder Füllen
207 möchte, gibt es die zwei \verb|canvas|-Methoden \verb|stroke| und
208 \verb|fill|, die jeweils den unmodifizierten Dekorator
209 \verb|deco.stroked| und \verb|deco.filled| zur Zeichenattributliste
210 hinzufügen. In Wirklichkeit ist Zeile 7 in Beispiel also identisch zu
211 \verb|c.show(p, [deco.stoked, style.linestyle.dashed, a])|. Hier
212 werden also Dekoratoren und Zeichenattribute auf der selben
213 Hierarchieebene gemischt, was bedeutet, dass die Zeichenattribute dann
214 für alle Dekoratoren zu verwenden sind. Soweit so gut, doch der
215 aufmerksame Leser mag einwenden, dass das gar nicht dem entspricht, was in der Abbildung gezeigt ist. Dort ist nämlich die
216 Umrandung des Pfeils nicht gestrichelt. In der Tat würde diese Linie
217 gestrichelt dargestellt, hätte nicht bereits der Pfeildekorator
218 \verb|deco.earrow.large| die Eigenschaft, den Linienstil für seinen
219 Wirkungsbereich auf durchgezogen zu schalten. Aber man kann dieses
220 Verhalten durch das zusätzliche Attribut \verb|deco.linestyle.clear|
221 auf der richtigen Hierarchieebene beim Modifizieren eines Dekorators
222 sogar wieder entfernen! Wenn man \verb|deco.linestyle.clear| in die
223 Liste \verb|d| einfügt, erhält man eine gestrichelte Pfeilumrandung.
225 Das Beispiel eben hat gezeigt, dass die Verknüpfung von
226 Zeichenattributen im Detail recht komplex werden kann. Gleichzeitig
227 ermöglicht \PyX{} es, solche komplexen Strukturen durch geeignete
228 Dekoratoren überhaupt darzustellen und einmal vorgefertigt immer
229 einsatzbereit zur Verfügung zu haben. Der Pfeildekorator, der
230 automatisch auf durchgezogene Linien schaltet, ist so ein Beispiel,
231 das zunächst unnötig komplex anmutet, aber im praktischen
232 Anwendungsfall beinahe immer automatisch das gewünschte Ergebnis liefert.
235 \section{Modifikation von Pfaden: Deformatoren}
237 Deformatoren werden dazu verwendet, einen gegebenen beliebigen Pfad in
238 einen anderen Pfad umzuwandeln. Ein ganz einfaches Beispiel sind
239 affine Transformationen wie die Translation oder die Rotation eines
240 Pfads. Mehrere solche Umformungen sind normalerweise nicht
241 kommutativ.
243 XXX hier kommt die komplizierte Methode vor der einfachen.
244 Ebenso wird gleich auf ein Problem (Hierarchieebenen) hingewiesen,
245 das für viele Benutzer gar keines sein dürfte.
247 Man kann Pfade explizit umformen, indem man die
248 \verb|deform|-Methode eines Deformators verwendet, aber es ist auch
249 möglich, Deformatoren bei der Ausgabe eines Pfades direkt anzuwenden.
250 Allerdings müssen die Deformatoren direkt auf der ersten
251 Hierarchieebene angegeben sein, können also nicht als Argumente von
252 Dekoratoren auftreten. Deformatoren werden dann stets in der
253 Reihenfolge ihres Auftretens noch vor dem Dekorieren auf den gegebenen
254 Pfad angewendet. Durch diese Einschränkungen bleibt das Ganze
255 durchschaubar und vor allem auch wohldefiniert. Trotzdem lassen sich
256 damit sehr elegante Ergebnisse erreichen, wie das folgende Beispiel zeigt,
257 das drei, kreisförmig angeordnete, durch Federn verbundene Massen darstellt.
258 \begin{quote}
259 \lstinputlisting{springs.py}
260 \end{quote}
261 \begin{figure}[tp]
262 \centerline{\includegraphics{springs}}
263 \caption{Feder-Beispiel}
264 \label{fig:springs}
265 \end{figure}
266 Das Ergebnis ist in Abbildung~\ref{fig:springs} zu sehen.
268 In den ersten zehn Zeilen dieses Beispiels wird wie vorher gezeigt das
269 \PyX-Paket geladen, ein paar Parameter definiert und eine
270 Zeichenfläche erzeugt. Interessant wird es ab Zeile 11, wo ein
271 kreisförmiger Pfad generiert wird, der später in die drei Federn
272 umgeformt werden soll. Dazu wird in Zeile 12 und 13 zunächst eine
273 Liste von Bogenlängen erzeugt, auf denen die Massen platziert werden.
274 Die Variable \verb|i| läuft mittels Python's \verb|range|-Funktion
275 über die Werte \verb|0|, \verb|1|, und \verb|2|. Mit der Schleife
276 beginnend auf Zeile 14 wird der ursprüngliche \verb|springcircle| in
277 drei Einzelteile zerlegt, die der Variable \verb|springsegment|
278 zugewiesen sind. Mit einem geeigneten Zykliod-Deformator kann dieses
279 Pfadstück in den Zeilen 15--17 direkt ausgegeben werden. Interessant
280 ist auch der zweite Deformator, der auf Zeile 17 steht. Dieser glättet
281 den gegeben Pfad, was in diesem Beispiel zu den etwas abgerundet
282 angedeuteten Übergängen zwischen den geraden Federendstücken und dem
283 gedrillten Federmittelstück führt. In Zeile 18 und 19 werden die drei
284 Massen gezeichnet und die Zeilen 20 und 21 fügen die beiden Kreise
285 hinzu, die das skizzierte Massesystem einschließen.
286 % Die Bestimmung der Schwingungsmoden dieses System soll hier nicht
287 % weiter verfolgt werden, gehört das doch eher in eine einführende
288 % Mechanik-Vorlesung denn in die Technische Komödie.
290 \section{Erzeugung von Text: die \TeX/\LaTeX-Integration}
292 Für die Textausgabe in \PyX{} wird \TeX{} oder alternativ \LaTeX{}
293 verwendet. Die Herausforderung besteht dabei darin, diese Programme
294 möglichst perfekt in das Graphiksystem zu integrieren. Zu diesem Zweck
295 ist im \verb|text|-Modul ein \verb|texrunner| implementiert, dessen
296 Instanzen jeweils ein laufendes \TeX{} oder \LaTeX{} steuern.
297 Normalerweise wird nur ein einziger solcher \verb|texrunner| benötigt und
298 dieser wird von dem System als \verb|defaulttexrunner| auch schon zu
299 Beginn initialisiert. Die wesentlichen Schritte bei der Erzeugung von
300 Text sind dann:
301 \begin{itemize}
302 \item \TeX{} oder \LaTeX{} wird als normaler Prozess gestartet und
303 überwacht. \PyX{} kann dann Dinge auf den Eingabestrom des Prozesses
304 schreiben und analysiert gleichzeitig, wie \TeX{} oder \LaTeX{} darauf
305 reagiert.
306 \item Sobald Text gesetzt werden muss, wird dieser von \PyX{} mit
307 entsprechenden Befehlen versehen, die den Text in eine Box setzen und
308 diese Box in der \verb|dvi|-Datei als einzelne Seite ausgeben. Die
309 Größe der Box wird direkt auf dem Ausgabestrom zurückgegeben und steht
310 instantan zur Verfügung steht. Auch merkt das System an dieser Stelle
311 zuverlässig, ob Probleme beim Setzen des Textes aufgetreten sind.
312 \item Sobald der gesetzte Text selbst benötigt wird, wird die
313 \verb|dvi|-Datei analysiert. Das ist in der Regel erst bei der
314 Erzeugung der Ausgabedateien nötig. Normalerweise muss \TeX{} bzw.
315 \LaTeX{} dazu beendet werden. Die \verb|texrunner|-Instanz macht dies
316 automatisch, wie auch das erneute Starten eines \TeX- bzw.
317 \LaTeX-Prozesses, falls das notwendig wird. Es besteht auch die
318 Möglichkeit, die \verb|ipc|-Option von \TeX/\LaTeX{} auszunutzen, so
319 sie in der vorhandenen \TeX-Installation zur Verfügung steht und damit
320 die \verb|dvi|-Datei zu analysieren, ohne \TeX{} bzw. \LaTeX{} beenden
321 zu müssen.
322 \item \PyX{} baut aus den Daten, die in der \verb|dvi|-Datei stehen,
323 entsprechenden PostScript- bzw. PDF-Code. Dabei werden momentan
324 ausschließlich Type1-Fonts verwendet, wie sie bei aktuellen
325 \TeX-Installation auch von dvips oder pdf\TeX{} benutzt werden.
326 \PyX{} arbeitet ähnlich zu diesen Programmen und verwendet die
327 vorhandene \TeX{}-Installation, löst also virtuelle Fonts auf,
328 schlägt in der vorliegenden \verb|map|-Datei nach und baut die
329 Type1-Fonts heruntergerechnet auf die benötigten Gylphen ein. Im
330 Grunde ist ein kleiner Teil von \PyX{} also ein \verb|dvips| und ein
331 \verb|dvipdf|.\footnote{In der Tat steht ein kleines Kommandozeilenprogramm zur
332 Verfügung, welches aus einer gegebenen \texttt{dvi}-Datei eine
333 PostScript oder eine PDF-Datei erzeugt. Eine solche Funktionalität ist
334 auf der Basis von \PyX{} mit einer handvoll Zeilen implementiert.}
335 \item Der \verb|dvi|-Interpreter von \PyX{} unterstützt einen
336 wohldefinierten Satz an \verb|\special|-Anweisungen. Eine Anpassung an
337 die \verb|graphic[s/x]|- und \verb|color|-Pakete wird mitgeliefert.
338 Darüber hinaus ist es möglich, im gesetzten Text sogenannte Marker
339 einzubauen und deren Position in der Ausgabe wiederzufinden.
340 \end{itemize}
342 Die Integration von \TeX/\LaTeX{} in \PyX{} bedeutet, dass man im
343 normalen Anwendungfall überhaupt nichts vom verwendeten \TeX/\LaTeX{}
344 merkt, außer, dass man für die Textausgabe einen echten
345 \TeX-Interpreter zur Hand hat und in programmiertechnischer Hinsicht
346 keinerlei Einschränkungen auferlegt sind. Wie das am Ende aussieht,
347 soll auch wieder an einem Beispiel demonstriert werden. Dazu folgendes
348 kleines Programm:
349 \begin{quote}
350 \lstinputlisting{text.py}
351 \end{quote}
352 Die entstehende Ausgabe lohnt nicht des Abdrucks als extra Abbildung
353 -- in der Ausgabedatei erscheint schlicht und einfach der angegebene Text.
355 Neu an diesem Beispiel ist nur die dritte Zeile, in der die
356 \verb|canvas|-Methode \verb|text| aufgerufen wird. Diese fügt einen
357 Text an der Position, die mit den ersten beiden Parametern beschrieben
358 wird, ein. Das \verb|r| vor der Zeichenkette führt dabei dazu, dass
359 das Zeichen \verb|\| innerhalb der Zeichenkette nicht als
360 \glqq{}escape\grqq-Zeichen interpretiert wird. Diese nützlichen
361 sogenannten \glqq{}raw-strings\grqq{} in Python sind natürlich
362 insbesondere für Zeichenketten, die \TeX{}-Syntax enthalten, sehr
363 praktisch. Ausführlicher geschrieben ist die dritte Zeile identisch zu
364 dem Befehl
365 \verb|c.insert(text.text(0, 0, r"Das ist eine Textausgabe mit \TeX."))|,
366 wobei die Funktion \verb|text.text| wiederum eine Abkürzung für den
367 Aufruf der Methode \verb|text| in der Instanz
368 \verb|text.defaulttexrunner| ist. Der Rückgabewert dieser
369 \verb|text|-Methode ist dabei eine spezielle Zeichenfläche, die den
370 Inhalt der jeweiligen \verb|dvi|-Seite enthält. Da man Zeichenflächen
371 per \verb|insert|-Methode ineinander einfügen kann, erscheint der
372 Inhalt der Seite in der Ausgabezeichenfläche, die in der Variablen
373 \verb|c| gespeichert ist. Statt die Ausgabe der \verb|text|-Methode in
374 die Ausgabe einzubinden, könnte man stattdessen natürlich auch
375 deren Größe abfragen oder ähnliches.
377 \begin{figure}[tp]
378 \centerline{\includegraphics{valign}}
379 \caption{Beispiel der vertikalen Ausrichtung von Text mittels
380 Textattributen}
381 \label{fig:valign}
382 \end{figure}
383 Abbildung~\ref{fig:valign} zeigt beispielhaft anhand verschiedener
384 vertikaler Ausrichtungsmethoden, was im Rahmen der \TeX-Integration in
385 \PyX{} möglich ist. Die Textausrichtung, wie auch viele andere
386 Eigenschaften, lassen sich dabei ganz einfach anhand von Attributen
387 setzen. Beispiele mit zugehörigem Quellcode finden sich auf der
388 \PyX-Beispielseite unter \url{http://pyx.sourceforge.net/examples/}.
390 \section{Komplexe Graphikaufgaben: Graphen}
392 Aufgrund der Praxisrelevanz für die Autoren wurde bereits zu einem
393 frühen Zeitpunkt in der \PyX-Entwicklung damit begonnen, Komponenten
394 für die Erstellung von Daten- und Funktionsgraphen zu implementieren.
395 Eine Designrichtlinie war dabei von Beginn an die Zerlegung eines
396 solchen Systems in Einzelteile, die möglichst unabhängig voneinander
397 sind und die mit einfachen Schnittstellen miteinander kommunizieren.
398 Die grobe Struktur des Systems lautet:
399 \begin{description}
400 \item[Graph:] Der eigentliche Graph wird durch eine Graph-Instanz
401 repräsentiert. Dieser legt die Graphengeometrie fest und dient als
402 Container für alle graph-spezifischen Daten.
403 \item[Achsen:] Die Achsen sind dafür zuständig, die Eingabedaten auf
404 das graphinterne Koordinatensystem umzurechnen. Dabei ist es möglich,
405 als Eingabedaten auch anderes als kontinuierliche Zahlen zu verwenden.
406 beispielsweise sind diskrete Achsen möglich, wie sie für die saubere
407 Implementation von Balkengraphen unverzichtbar sind. Auch
408 Achsenteilungen
409 % XXX was meinst Du hier mit Achsenteilungen? Splitaxis?
410 sind möglich, indem man kontinuierliche Achsen in
411 diskret geteilte Achsen schachtelt.
413 Außerdem müssen Achsen eine graphische Repräsentation ihrer selbst
414 entlang eines beliebigen Pfades erzeugen können, was wiederum durch
415 eine Reihe von Einzelkomponenten erledigt wird:
416 \begin{description}
417 \item[Achsenteilung:] Bestimmung von Achsenteilungen, wobei manuell
418 gesetzte Achsenstriche mit automatisch erzeugten Achsenstrichen
419 gemischt werden können. Die Achsenteilung für normale Zahlenachsen
420 basiert auf rationalen Zahlen und ist frei von jeglichen
421 Rundungsproblemen.
422 \item[Beschriftung von Achsenstrichen:] Die Erzeugung von Text passend
423 zu den Achsenstrichen ist als getrennte Komponente ausgeführt und
424 somit leicht änderbar.
425 \item[Bewertung von Achsenteilungen:] Bei automatischer Achsenteilung
426 sind normalerweise verschiedene Teilungen möglich, die bewertet werden
427 müssen, um die beste Teilung zu finden. Dabei werden auch Abstände
428 zwischen den Texte der Achsenstriche hinzugezogen.
429 \item[Zeichner:] Der Zeichner ist eine Komponente, die die Ausgabe der
430 Achse ausführt. Auch dieser Teil lässt sich anpassen oder auch
431 komplett ersetzen.
432 \end{description}
433 \item[Daten:] Verschiedene Datenkomponenten bereiten Eingabedaten
434 gegeben durch Zahlenspalten einer Datei, durch eine Funktion oder
435 anderen Quellen für die Benutzung im Graphsystem vor. Insbesondere
436 werden die Daten dabei mit Spaltennamen versehen, was die spätere
437 Zuordnung zu Achsen oder Stileigenschaften ermöglicht.
438 \item[Stile:] Graphstile erzeugen aus den eingehenden Daten eine
439 graphische Repräsentation. Es gibt also beispielsweise Stile zum
440 Zeichnen von Symbolen, Linien und Fehlerbalken und vieles andere mehr.
441 Interessant ist die Eigenschaft, dass sich verschiedene Stile
442 gleichzeitig auf Daten anwenden lassen. Außerdem lassen sich durch
443 Implementation eigener Stile Dinge realisieren, die zunächst überhaupt
444 nicht nach einem Graph aussehen sondern eher beispielsweise wie eine
445 Tabelle. Dabei lässt sich dann aber gleichzeitig die
446 Komponentenstruktur eines Graphen ausnutzen.
447 \item[Legende:] Eine Legende schließlich erzeugt eine graphische
448 Darstellung, die Stile mit Titeln der gezeigten Daten verknüpft.
449 \end{description}
451 Die Flexibilität des Graphsystems führt zu einer entsprechend großen
452 Anzahl unterschiedlicher Anwendungsbeispiele. An dieser Stelle soll
453 nur ein einfaches Beispiel gezeigt werden, um die prinzipielle
454 Funktionsweise vorzustellen. Darüber hinaus ist ein Besuch auf der
455 \PyX-Beispielseite unter \url{http://pyx.sourceforge.net/examples/}
456 sehr zu empfehlen.
458 \begin{figure}[tp]
459 \centerline{\includegraphics{piaxis}}
460 \caption{Graph-Beispiel}
461 \label{fig:piaxis}
462 \end{figure}
463 Die Abbildung~\ref{fig:piaxis} wird durch folgendes Programm erzeugt:
464 \begin{quote}
465 \lstinputlisting{piaxis.py}
466 \end{quote}
467 In Zeile 1 wird die Variable \verb|pi| aus dem \verb|math| Modul von
468 Python geladen. Dann folgt wieder der übliche Import der \PyX-Module.
469 In Zeile 3 und 4 werden zwei Klassen direkt importiert. Durch Zeile 3
470 wird beispielsweise erreicht, dass eine lineare Achse statt unter
471 ihrem langen Namen \verb|pxy.graph.axis.linear| direkt unter dem Namen
472 \verb|linear| zur Verfügung steht. In den Zeilen 6 bis 9 wird eine
473 Graph-Instanz \verb|g| angelegt. Als Grapheigenschaften werden dabei
474 unter anderem \verb|x| und \verb|y|-Achsen mit speziellen
475 Einstellungen explizit gesetzt. In Zeile 11 und 12 werden zwei
476 Funktionen zum Graph hinzugefügt und schon ist alles fertig und kann
477 in Zeile 14 in einer Datei gesichert werden.
479 \section{Entwicklung von \PyX}
481 XXX wie gesagt -> löschen (bis auf den letzten Absatz)
483 Aber: wir brauchen noch was zu den ausgefalleneren TeX-Sachen
484 und einen Ausblick in die Zukunft.
487 Das \PyX-Projekt ist, wie wohl die Mehrzahl der OpenSource-Projekte,
488 zunächst aus Eigenbedarf der beiden Projektgründer und
489 Hauptentwickler, Jörg Lehmann und André Wobst, Mitte 2000 gestartet
490 wurden. Diesem Start eines sich schon seinerzeit abzeichnenden
491 langwierigen Entwicklungsprozesses gingen zahlreiche Diskussionen und
492 Tests existierender anderer Lösungen voraus. Ursprünglich waren die
493 Entwickler Benutzer von GLE (\url{http://glx.sourceforge.net/}), was
494 sich wie \PyX{} auch vor allem dadurch auszeichnete, dass sich damit
495 Zeichnungen wie auch Daten- und Funktionsgraphen erstellen lassen. Die
496 fehlende \TeX-Anbindung wurde durch gletex
497 (\url{http://www.physik.uni-augsburg.de/~wobsta/gletex/}) im Rahmen
498 der bescheidenen Möglichkeiten hinzugefügt, aber das eigentliche
499 Problem der völlig fehldesignten GLE-eigenen Sprache konnte auf die
500 Weise nicht angegangen werden. Zunächst trennten sich die Wege der
501 Entwickler (auch räumlich) und während Jörg Lehmann versuchte, eine
502 GLE-Ersatzlösung auf der Basis von Perl und einem GLE-Übersetzer zu
503 starten und André Wobst einlud, daran mitzuwirken, beschäftigte sich
504 dieser lieber mit Graphen-Lösungen auf der Basis von
505 {\font\logo=logo10\logo{}METAPOST}, allerdings am Ende frustriert ob
506 der Probleme aufgrund der für dieses Problem ungeeigneten, zu sehr auf
507 Zeichnen spezialisierten und ansonsten unhandlich unvollständigen
508 Sprache.
510 Als schließlich die Entwickler wieder zusammentrafen, starteten sie
511 das \PyX-Projekt auf der Basis der Programmiersprache Python und
512 verwarfen die Idee, eine vollständige sprachliche GLE-Kompatibilität
513 zu schaffen. Gleichwohl besaßen frühe Versionen eine
514 Endbenutzer-Sprachschicht, die allein mit Funktionsaufrufen und nicht
515 mit Objektinstanzen arbeitete. Allerdings liessen sich in Python keine
516 Strukturen schaffen, die einem GLE-typischen Abschnitt zur
517 Beschreibung eines Graphen entsprachen, weshalb hier relativ bald auf
518 Objektmethoden ausgewichen wurde. Schließlich setzte sich die
519 Benutzung von Objektinstanzen auch für Zeichenflächen, Pfade und
520 dergleichen durch. In den ersten frühen Versionen wurde übrigens
521 \verb|dvips| verwendet, um \TeX{} anzubinden. Erst deutlich später
522 wurden die Einschränkungen, die diese Lösung mit sich brachte, Grund
523 genug ein eigenen \verb|dvi|-Parser zu schreiben. Bereits 2001 wurden
524 die Grundlagen soweit fertig, dass Ende 2001 für das Erzeugen einer
525 komplexen Tabelle das erste Mal \PyX{} den Vorzug gegenüber einer
526 \TeX{} bzw. \LaTeX{} Lösung bekam. Im Frühjahr 2002 wurde das erste
527 Mal ein A0-Poster mit \PyX{} erstellt, wobei die Graphen noch mit GLE
528 erzeugt wurden. Zu diesem Zeitpunkt wurde der Quellcode
529 einschließlich seiner Geschichte bis zurück ins Jahr 2000 bei
530 SourceForge veröffentlicht. Im Herbst 2002 wurde \PyX{} 0.1
531 freigegeben und seit Version 0.3.1 vom April 2003, die auf freshmeat
532 bekanntgegeben wurde, erfreut sich das Projekt zunehmender Nutzung
533 auch durch nicht den Entwicklern nahestehenden Personen. Zudem wurden
534 mit Michael Schindler und Gert-Ludwig Ingold zwei Mitstreiter
535 gewonnen, die das Projekt zusätzlich voranbringen.
537 Die Entwicklung von \PyX{} ist aber keineswegs ein geradliniger
538 Prozess. Insbesondere hat die Erarbeitung von effizienten Strukturen
539 für den Endanwender viele Entwicklungsschritte und deshalb auch
540 inkompatible Veränderungen zwischen den Versionen notwendig gemacht.
541 Mittlerweile sind viele der Strukturen aber schon sehr ausgereift und
542 stabil, wie man auch an den immer wieder neu freigegebenen Versionen
543 beobachten kann. Die aktuelle Version \PyX{} 0.8.1 vom August 2005
544 wird von den Entwicklern jedoch nach wie vor als Alpha-Release
545 bezeichnet, was vor allem ausdrücken soll, dass in bestimmten
546 Bereichen noch Aktualisierungen geplant sind, die zumindest teilweise
547 auch vom Anwenderstandpunkt aus sichtbar sein werden. Nachdem aber
548 bereits sehr viele \PyX-Programme existieren, sind größere, nicht
549 einfach handhabbare Umstellungen in zukünftigen Versionen zunehmend
550 sehr unwahrscheinlich.
552 An dieser Stelle möchten wir uns ganz herzlich bei DANTE e.V. und
553 dessen Vorstand bedanken, der im Sommer 2004 auf eine Anfrage hin ganz
554 unbürokratisch zugestimmt hat, die relativ regelmäßig drei bis vielmal
555 im Jahr stattfindenden Entwicklertreffen finanziell durch die
556 Übernahme von anfallenden Fahrtkosten zu unterstützen. Durch die
557 mittlerweile wieder vorhandene räumliche Trennung der Hauptentwickler
558 ist diese Förderung enorm wichtig für die erfolgreiche Fortführung des
559 Projekts.
561 \end{document}