image image


image

FPlotter in Processing.py: Ich habe fertig!

Heute habe ich mich hingesetzt und die versprochenen abschließenden Arbeiten an FPlotter, der selbstgebauten Matplotlib für Arme (in Processing.py) durchgeführt. Sprich: Ich habe dem Teil noch eine Achsenbeschriftung verpaßt. Dafür war gar nicht mehr so viel zu programmieren:

In der Deklaration des Zeichenbereichs mußten wegen einiger notwendigen, größeren Abstände, ein paar Konstanten geändert und die Konstanten label_x und label_y neu deklariert werden:

plot_x1 = 120
plot_x2 = WIDTH - 80 # WIDTH - plot_x1
label_x = 50
plot_y1 = 60
plot_y2 = HEIGHT - plot_y1
label_y = HEIGHT - 25

Ebenfalls neu ist die Funktion draw_axis_labels(), die im Hauptprogramm zwischen draw_grid() und draw_function() aufgerufen wird:

def draw_axis_labels():
    fill(0, 150, 0)
    textSize(13)
    textLeading(15)
    textAlign(CENTER, CENTER)
    text("y = sin(x)", label_x, (plot_y1 + plot_y2)/2)
    textAlign(CENTER)
    text(u"x-Werte (-10 … 10)", (plot_x1 + plot_x2)/2, label_y)

Ich bin Ben Fry gefolgt und habe die Beschriftung der y-Achse nicht vertikal rotiert. Da die Relationen alle mit der map()-Funktion der Zeichenfläche angepaßt werden, wollte ich die Freiheit ausnutzen und die Beschriftung horizontal lassen, damit ich zum Lesen den Kopf nicht immer auf die Seite drehen muß. 🤓

Sollte sie dennoch für ein Projket mal zu lange werden, kann man sie immer noch mit transform() und rotate() um 180° drehen.

Jetzt erst einmal der vollständige Sketch:

# 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 = 120
plot_x2 = WIDTH - 80 # WIDTH - plot_x1
label_x = 50
plot_y1 = 60
plot_y2 = HEIGHT - plot_y1
label_y = HEIGHT - 25

# 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_axis_labels()
    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)

def draw_axis_labels():
    fill(0, 150, 0)
    textSize(13)
    textLeading(15)
    textAlign(CENTER, CENTER)
    text("y = sin(x)", label_x, (plot_y1 + plot_y2)/2)
    textAlign(CENTER)
    text(u"x-Werte (-10 … 10)", (plot_x1 + plot_x2)/2, label_y)

Natürlich ist dieses kleine Skript kein Ersatz für die Matplotlib, das soll es auch gar nicht sein. Aber wie angekündigt möchte ich in der nächsten Zeit einige grundlegende numerische Methoden vorstellen und in Python (Processing.py) implementieren, ohne die Numerik-Boliden Numpy und Scipy zu nutzen. Dadurch verspreche ich mir ein besseres Verständnis numerischer Probleme. Und da liegt es natürlich nahe, konsequent die Visualisierung auch ohne die Matplotlib durchzuführen.

Es mag ein wenig danach klingen, als ob ich das Rad erneut erfinden will. Aber während meines Studiums – lang, lang ist es her – wurden wir Studenten angehalten, numerische Algorithmen und Methoden erst einmal von Hand zu implementieren und erst dann die »großen« FORTRAN-Pakete zu nutzen. Das hat meinem Verständnis der Numerik nicht geschadet – im Gegenteil!


(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