2009-08-17 190 views
3

如何用Pyx在兩個任意點之間繪製「支撐」線?用Pyx繪製花括號

這將是這個樣子:

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

+0

看起來像你創建一個畫布,找到兩個端點之間的點,爲p1畫一條垂直線到半途,在中途點畫出某種乳頭,然後從中途畫一條垂直線到p2。使用c.stroke(path.line(p1.x,p2.y,halfway.x,halfway.y)))和c.stroke(path.line(halfway.x,halfway.y,p1.x,p2。 Y)))。或者其他的東西。我沒有安裝這個軟件包來回答這個問題。 – hughdbrown 2009-08-17 18:55:57

+2

@hughbrown:你爲什麼不把你的答案作爲答案? – 2009-08-17 19:00:16

+0

我沒有安裝此軟件包。我想我可以勾畫出一個近似的答案,巴斯蒂安可以用它來運行。 – hughdbrown 2009-08-17 19:53:38

回答

9

您可以繪製使用sigmoidals相當大括號。我沒有安裝Pyx,所以我只是使用matplotlib(這裏是pylab)繪製這些圖。這裏beta控制大括號中曲線的清晰度。

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

我策劃了這沿x軸,以節省屏幕空間,但相處y軸支架只是交換x和y。最後,Pyx還有很多內置的路徑繪製功能,它們也可以滿足您的需求。

+0

嘿,我特別想知道你是怎麼寫half_brace方法的。你做的數學是一種常見的標準東西嗎?你能幫我指出一些資源來學習嗎? – asyncwait 2009-08-28 09:10:41

+0

@Vadi - 我在答案的第一行添加了一個到sigmoid函數的鏈接。 half_brace函數是兩個sigmoidals的總和,我只是認爲總和比將它分成四個部分更容易。 Sigmoidals本身相當普遍,但這取決於你的觀點。例如在物理學中(但是在比基礎本科更先進的話題中),它們直接表現爲費米 - 狄拉克分佈函數。 – tom10 2009-08-28 21:26:36

+0

@ tom10,你的壞蛋 – 2013-04-11 18:05:17

4

tom10提供了一個很好的解決方案,但可以使用一些改進。
關鍵是在範圍[0,1],[0,1]上創建一個大括號,然後對其進行縮放。
這個版本還可以讓你調整一下形狀。對於獎勵積分,它使用二階導數來計算多少密集間隔點。

mid設置下部和上部之間的平衡。
beta1beta2控制曲線(下和上)有多銳。
您可以更改height(或者僅將y乘以標量)。
使它垂直而不是水平只需要交換x和y。
initial_divisionsresolution_factor指導如何選擇x值,但通常應該是可以忽略的。

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) 

用法很簡單:

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:不要忘了,你可以通過clip_on=Falseplot,並把它的軸線之外。