image image


image

FPlotter – Matplotlib selbstgebaut (mit Processing.py)

Das Modul GPanel für zweidimensionale Graphen in TigerJython ist ja ganz nett, aber mir fehlten da doch etliche ästhetisch befriedigende Eingriffsmöglichkeiten (denn Mathematik macht nicht nur Spaß, sondern ist auch schön – und dem standen die pixeligen Fonts von GPanel im Wege). Daher habe ich versucht, so etwas mal in Processing(.py) zu implementieren. Da es auf den unterschiedlichsten Wertebereichen funktionieren sollte, habe ich ganz gewaltig mit der map()-Funktion von Processing herumgehampelt. Soweit wie obiger Screenshot zeigt, bin ich gestern gekommen. In den nächsten Tagen möchte ich noch Beschriftungsmöglichkeiten für die x- und y-Achse implementieren (das ist für publikationsfähige Plots unbedingt derforderlich). Und wenn ich dann noch einen PDF-Export (für Pandoc, LaTeX und Freunde) hinbekomme, ist das schon fast so etwas wie eine (2D-) Matplotlib für Processing(.py) (und für Arme 🤓).

Inspiriert wurde dieses Projekt durch zwei Quellen: Die erste Quelle war das ziemlich geniale Buch »Visualizing Data« von Ben Fry, das im vierten Kapitel Time Series etwas ähnliches in Processing (Java) implementiert und die zweite Quelle war Peter Farrell, der in »Math Adventures with Python« ebenfalls einen einfachen Funktionenplotter baut (S. 63ff). Ich habe mir das Beste aus diesen beiden Quellen herausgepickt und dadurch dieses Skript erhalten:

# Processing(.py) Graphing Tool
# Inspired from »Visualizing Data« (Ben Fry) and
# »Math Adventures with Python« (Peter Farrell)

import math

WIDTH = 720
HEIGHT = 450

dt = 0.05

# Zeichenbereich
plot_x1 = 50
plot_x2 = WIDTH - plot_x1
plot_y1 = 60
plot_y2 = HEIGHT - plot_y1

# Titel
plot_title = u"Sinuskurve"

# Funktionsabhängige Konstanten
x_min = -10
x_max = 10
y_min = -2
y_max = 2
stepsize_x = 2   # Ticks auf der x-Achse
stepsize_y = -1  # Ticks auf der y-Achse

def setup():
    size(WIDTH, HEIGHT)
    this.surface.setTitle("Funktionsplotter")
    plot_font = createFont("American Typewriter", 20)
    textFont(plot_font)
    noLoop()
    
def draw():
    background(234, 218, 184)
    # Den Plot in einem weißen Kasten zeichnen
    fill(255)
    rectMode(CORNERS)
    noStroke()
    rect(plot_x1, plot_y1, plot_x2, plot_y2)
    # Title des Plots
    fill(0, 150, 0)
    textSize(20)
    textAlign(LEFT)
    text(plot_title, plot_x1, plot_y1 - 10)
    draw_grid()
    draw_function()
    print("I did it, Babe!")
    
def f(x):
    return(math.sin(x))

def draw_function():
    stroke(255, 0, 0)
    x = x_min
    while x <= x_max - dt:
        x_0 = map(x, x_min, x_max, plot_x1, plot_x2)
        x_1 = map(x + dt, x_min, x_max, plot_x1, plot_x2)
        y_0 = map(f(x), y_min, y_max, plot_y2, plot_y1)
        y_1 = map(f(x + dt), y_min, y_max, plot_y2, plot_y1)
        line(x_0, y_0, x_1, y_1)
        x += dt
    
def draw_grid():
    # Zeichnet Gitter und Label
    textSize(10)
    textAlign(CENTER, TOP)
    # x-Achse
    for i in range(x_min, x_max + 1, stepsize_x):
        x = map(i, x_min, x_max, plot_x1, plot_x2)
        fill(0, 150, 0)
        text(str(i), x, plot_y2 + 10)
        strokeWeight(1)
        stroke(0, 255, 255)
        line(x, plot_y1, x, plot_y2)
    # y-Achse
    for j in range (y_max, y_min - 1, stepsize_y):
        y = map(j, y_max, y_min, plot_y1, plot_y2)
        if j == y_min:
            textAlign(RIGHT, BOTTOM)  # Unten
        elif j == y_max:
            textAlign(RIGHT, TOP)     # Oben
        else:
            textAlign(RIGHT, CENTER)  # Vertikal zentrieren
        fill(0, 150, 0)
        text(str(j), plot_x1 - 10, y)
        strokeWeight(1)
        stroke(0, 255, 255)
        line(plot_x1, y, plot_x2, y)

Die eigentliche Arbeit wird in den Funktionen draw_grid() und draw_function() geleistet, die genau das erledigen, was der Name schon andeutet. f(x) ist die zu zeichnende Funktion, deren Funktionskonstanten jeweils angepaßt werden müssen. Mit den Konstanten WIDTH und HEIGHT kann ich die Fenstergröße nach Wunsch anpassen, alle variablen Parameter für den Zeichenbereich werden durch diese Konstanten gesteuert.

Eine Besonderheit ist noch in der Beschriftung der y-Achse verborgen: Die jeweils oberste und unterste Ziffer wird ein wenig nach oben respektive unten verschoben, damit sie jeweils mit der Zeichenbox abschließt. Diese geniale Idee habe ich schamlos bei Ben Fry geklaut.

So gefällt mir das Teil schon recht gut, jedoch werde ich es – wie oben versprochen – in den nächsten Tagen noch ein wenig aufbohren. Denn ich habe Seltsames damit vor. Still digging!


(Kommentieren) 

image image



Über …

Der Schockwellenreiter ist seit dem 24. April 2000 das Weblog digitale Kritzelheft von Jörg Kantel (Neuköllner, EDV-Leiter Rentner, Autor, Netzaktivist und Hundesportler — Reihenfolge rein zufällig). Hier steht, was mir gefällt. Wem es nicht gefällt, der braucht ja nicht mitzulesen. Wer aber mitliest, ist herzlich willkommen und eingeladen, mitzudiskutieren!

Alle eigenen Inhalte des Schockwellenreiters stehen unter einer Creative-Commons-Lizenz, jedoch können fremde Inhalte (speziell Videos, Photos und sonstige Bilder) unter einer anderen Lizenz stehen.

Der Besuch dieser Webseite wird aktuell von der Piwik Webanalyse erfaßt. Hier können Sie der Erfassung widersprechen.

Diese Seite verwendet keine Cookies. Warum auch? Was allerdings die iframes von Amazon, YouTube und Co. machen, entzieht sich meiner Kenntnis.


Werbung

Diese Spalte wurde absichtlich leergelassen!


Werbung


image  image  image
image  image  image


image