2009-08-17 4 views
3

Wie kann ich eine gestrichelte Linie zwischen zwei beliebigen Punkten mit Pyx zeichnen?Zeichenketten mit Pyx

Es würde wie folgt aussehen:

Brace example http://tof.canardpc.com/view/d16770a8-0fc6-4e9d-b43c-a11eaa09304d

+0

Es sieht so aus, als ob Sie eine Leinwand erstellen, den Punkt zwischen den beiden Endpunkten finden, eine vertikale Linie für p1 bis zur Hälfte zeichnen, eine Art Nippel an der Mitte zeichnen und dann eine vertikale Linie von der Mitte bis p2 zeichnen. Verwenden Sie c.stroke (Pfad.line (p1.x, p2.y, halfway.x, halfway.y))) und c.stroke (Pfad.line (halfway.x, halfway.y, p1.x, p2. y))). Oder so. Ich installiere dieses Paket nicht, um diese Frage zu beantworten. – hughdbrown

+2

@hughbrown: Warum hast du deine Antwort nicht als Antwort gepostet? –

+0

Ich habe dieses Paket nicht installiert. Ich dachte, ich könnte eine ungefähre Antwort skizzieren und Bastien könnte damit rennen. – hughdbrown

Antwort

9

Sie ziemlich Klammern sigmoidals mit ziehen. Ich habe Pyx nicht installiert, also werde ich diese nur mit Matplotlib (pylab hier) plotten. Hier steuert beta die Schärfe der Kurven in den Zahnspangen.

import numpy as nx 
import pylab as px 


def half_brace(x, beta): 
    x0, x1 = x[0], x[-1] 
    y = 1/(1.+nx.exp(-1*beta*(x-x0))) + 1/(1.+nx.exp(-1*beta*(x-x1))) 
    return y 

xmax, xstep = 20, .01 
xaxis = nx.arange(0, xmax/2, xstep) 
y0 = half_brace(xaxis, 10.) 
y = nx.concatenate((y0, y0[::-1])) 

px.plot(nx.arange(0, xmax, xstep), y) 
px.show() 

alt text http://i26.tinypic.com/23iyp76.png

I aufgetragen dies entlang der x-Achse Platz auf dem Bildschirm zu sparen, sondern entlang der y-Achse Klammern nur tauschen x und y zu erhalten. Schließlich verfügt Pyx über zahlreiche integrierte Funktionen zum Zeichnen von Pfadangaben, die auch für Ihre Anforderungen geeignet sind.

+0

Hey, ich bin besonders daran interessiert zu wissen, wie du die Methode half_brace geschrieben hast. Ist die Mathematik, die du machst, ein übliches Standardmaterial? Kannst du mir helfen, mir einige Ressourcen zu zeigen, um das zu lernen? – asyncwait

+0

@Vadi - Ich habe einen Link zu Sigmoid-Funktionen in der ersten Zeile der Antwort hinzugefügt. Die half_brace-Funktion ist die Summe von zwei Sigmoidalen, und ich dachte einfach, dass es einfacher ist, die Summe zu machen, als dies in vier Teile zu teilen. Sigmoidale selbst sind ziemlich häufig, aber das hängt von Ihrer Perspektive ab. In der Physik zum Beispiel (aber in Themen, die weiter fortgeschritten sind als Grundkenntnisse) erscheinen diese direkt als die Fermi-Dirac-Verteilungsfunktion. – tom10

+0

@ tom10, Sie Badass –

4

Tom10 bietet eine gute Lösung, könnte aber einige Verbesserungen verwenden.
Der Schlüssel erzeugt eine Klammer über den Bereich [0,1], [0,1] und skaliert sie dann.
Diese Version ermöglicht es Ihnen auch, die Form ein wenig zu optimieren. Für Bonuspunkte verwendet es die zweite Ableitung, um herauszufinden, wie dicht die Punkte sind.

mid legt das Gleichgewicht zwischen den unteren und oberen Teilen fest.
beta1 und beta2 steuern, wie scharf die Kurven (unten und oben) sind.
Sie können die height ändern (oder einfach y mit einem Skalar multiplizieren).
Um es vertikal statt horizontal zu machen, müssen nur x und y getauscht werden.
initial_divisions und resolution_factor bestimmen, wie die x-Werte gewählt werden, sollten aber generell ignoriert werden.

import numpy as NP 

def range_brace(x_min, x_max, mid=0.75, 
       beta1=50.0, beta2=100.0, height=1, 
       initial_divisions=11, resolution_factor=1.5): 
    # determine x0 adaptively values using second derivitive 
    # could be replaced with less snazzy: 
    # x0 = NP.arange(0, 0.5, .001) 
    x0 = NP.array(()) 
    tmpx = NP.linspace(0, 0.5, initial_divisions) 
    tmp = beta1**2 * (NP.exp(beta1*tmpx)) * (1-NP.exp(beta1*tmpx))/NP.power((1+NP.exp(beta1*tmpx)),3) 
    tmp += beta2**2 * (NP.exp(beta2*(tmpx-0.5))) * (1-NP.exp(beta2*(tmpx-0.5)))/NP.power((1+NP.exp(beta2*(tmpx-0.5))),3) 
    for i in range(0, len(tmpx)-1): 
     t = int(NP.ceil(resolution_factor*max(NP.abs(tmp[i:i+2]))/float(initial_divisions))) 
     x0 = NP.append(x0, NP.linspace(tmpx[i],tmpx[i+1],t)) 
    x0 = NP.sort(NP.unique(x0)) # sort and remove dups 
    # half brace using sum of two logistic functions 
    y0 = mid*2*((1/(1.+NP.exp(-1*beta1*x0)))-0.5) 
    y0 += (1-mid)*2*(1/(1.+NP.exp(-1*beta2*(x0-0.5)))) 
    # concat and scale x 
    x = NP.concatenate((x0, 1-x0[::-1])) * float((x_max-x_min)) + x_min 
    y = NP.concatenate((y0, y0[::-1])) * float(height) 
    return (x,y) 

Die Verwendung ist einfach:

import pylab as plt 

fig = plt.figure() 
ax = fig.add_subplot(111) 

x,y = range_brace(0, 100) 
ax.plot(x, y,'-') 

plt.show() 

Plot produced by example

PS: Vergessen Sie nicht, dass Sie clip_on=False zu plot und legte sie außerhalb der Achse passieren kann.

Verwandte Themen