使用bokeh繪圖

bokeh

由於mpld3沒有支援Python 3.5,測試過執行產生的頁面是空白頁,所以選擇使用bokeh來繪製,但是後者不支援3D繪圖。

使用Anaconda的指令安裝bokeh。

1
ana install bokeh

參照了一下官方的說明頁:

  1. http://bokeh.pydata.org/en/latest/docs/installation.html

  2. http://bokeh.pydata.org/en/latest/docs/reference/io.html

  3. http://bokeh.pydata.org/en/latest/docs/user_guide/notebook.html


Exercise

將之前的Crank Rocker改寫一下鏈

#一三角形呆鍊,由一長一短的連桿固定在水平基線上。
#短連桿鎖固在原點上,長連鏈鎖固在距原點90mm處。
#短連桿長度35mm;長連桿長度70mm。
#三角形呆鍊邊長分別為40mm、40mm、70mm
from slvs import *
from math import *
from bokeh.plotting import figure, output_file, show

#相關參數
d0 = 90 #基線長度(mm)
n1 = 35 #短連桿長度(mm)
n2 = 70 #長連桿長度(mm)
t1 = 40 #三角形第一邊(mm)
t2 = 40 #三角形第二邊(mm)
t3 = 70 #三角形第三邊(mm)

#開始繪圖

def crank_rock(degree):

    sys = System(500)
    g = 1
    #原點Point0
    p0 = sys.add_param(0.0)
    p1 = sys.add_param(0.0)
    p2 = sys.add_param(0.0)
    Point0 = Point3d(p0, p1, p2)

    #XY法線
    qw, qx, qy, qz = Slvs_MakeQuaternion(1, 0, 0, 0, 1, 0)
    p3 = sys.add_param(qw)
    p4 = sys.add_param(qx)
    p5 = sys.add_param(qy)
    p6 = sys.add_param(qz)
    Normal1 = Normal3d(p3, p4, p5, p6)

    #工作平面
    Workplane1 = Workplane(Point0, Normal1)

    #3D版的Point0=>Point1
    p7 = sys.add_param(0.0)
    p8 = sys.add_param(0.0)
    Point1 = Point2d(Workplane1, p7, p8)
    Constraint.dragged(Workplane1, Point1)

    #長連桿轉軸Point2,還有基線Line0。
    p9 = sys.add_param(d0)
    p10 = sys.add_param(0.0)
    Point2 = Point2d(Workplane1, p9, p10)
    Constraint.dragged(Workplane1, Point2)
    Line0 = LineSegment2d(Workplane1, Point1, Point2)

    #Angle約束判斷
    if degree >= 180:
        other = -1
    else:
        other = 1

    #三角形Point3 / Point4 / Point5
    p11 = sys.add_param(20.0)
    p12 = sys.add_param(20.0)
    Point3 = Point2d(Workplane1, p11, p12)
    p13 = sys.add_param(0.0)
    p14 = sys.add_param(10.0*other)
    Point4 = Point2d(Workplane1, p13, p14)
    p15 = sys.add_param(30.0)
    p16 = sys.add_param(20.0)
    Point5 = Point2d(Workplane1, p15, p16)
    Constraint.distance(t1, Workplane1, Point4, Point3)
    Constraint.distance(t2, Workplane1, Point3, Point5)
    Constraint.distance(t3, Workplane1, Point4, Point5)

    #連桿約束
    Constraint.distance(n1, Workplane1, Point1, Point4)
    Constraint.distance(n2, Workplane1, Point2, Point5)
    Line1 = LineSegment2d(Workplane1, Point1, Point4)

    #短連桿與水平軸的角度
    Constraint.angle(Workplane1, degree, Line1, Line0, False)

    #以下解題

    sys.solve()

    if (sys.result == SLVS_RESULT_OKAY):
        x = sys.get_param(11).val
        y = sys.get_param(12).val
        return x, y
    elif (sys.result == SLVS_RESULT_INCONSISTENT):
        print ("solve failed")
        print ("SLVS_RESULT_INCONSISTENT")
        print ("%d DOF" % sys.dof)
    elif (sys.result == SLVS_RESULT_DIDNT_CONVERGE):
        print ("solve failed")
        print ("SLVS_RESULT_DIDNT_CONVERGE")
        print ("%d DOF" % sys.dof)
    elif (sys.result == SLVS_RESULT_TOO_MANY_UNKNOWNS):
        print ("solve failed")
        print ("SLVS_RESULT_TOO_MANY_UNKNOWNS")
        print ("%d DOF" % sys.dof)

#主程式
Xval  = []
Yval  = []

for i in range(0, 361):
    x, y = crank_rock(i)
    Xval += [x]
    Yval += [y]
print ("Solve Completed")

#bokeh
output_file("mango.html")
plot = figure(title="simple line example", x_axis_label='x', y_axis_label='y')
plot.line(Xval, Yval, legend="Temp.", line_width=2)
show(plot)

使用的是簡單的show指令,會產生一個html的檔案。

內容是和matplotlib一樣的圖形。

另外bokeh也可以在Jupyter notebook上使用。

from tmp.workplace.exposed.slvs import *
from math import *
from bokeh.plotting import figure, output_notebook, show

d0 = 90 #基線長度(mm)
n1 = 35 #短連桿長度(mm)
n2 = 70 #長連桿長度(mm)
t1 = 40 #三角形第一邊(mm)
t2 = 40 #三角形第二邊(mm)
t3 = 70 #三角形第三邊(mm)

#開始繪圖

def crank_rock(degree):
    ...

#主程式
Xval  = []
Yval  = []

for i in range(0, 361):
    x, y = crank_rock(i)
    Xval += [x]
    Yval += [y]
print ("Solve Completed")

#bokeh
output_notebook()
plot = figure(title="simple line example", x_axis_label='x', y_axis_label='y')
plot.line(Xval, Yval, legend="Temp.", line_width=2)
show(plot)

程式庫名稱必須改為tmp.workplace.exposed.slvs

執行結果如下:

另一支跑手臂極限範圍的程式:


有找到另一個套件Vispy可以畫3D物件,也可以在Jupyter notebook上執行。

另外Solvespace的運算方面無法同時計算2D和3D的物件,儲存的項目也不一樣。

不知道能不能用球座標系或圓柱坐標系轉換的方式,做一個將3D點鎖定到2D點的功能。


Comments

comments powered by Disqus