plotly

      在〈plotly〉中尚無留言

Simple Slider Control

#!/usr/bin/python3
import plotly.graph_objects as go
import numpy as np
import plotly

# Create figure
fig = go.Figure()

# Add traces, one for each slider step
for step in np.arange(0, 5, 0.1):
    fig.add_trace(
        go.Scatter(
            visible=False,
            line=dict(color="#00CED1", width=6),
            name="𝜈 = " + str(step),
            x=np.arange(0, 10, 0.01),
            y=np.sin(step * np.arange(0, 10, 0.01))))

# Make 10th trace visible
fig.data[10].visible = True

# Create and add slider
steps = []
for i in range(len(fig.data)):
    step = dict(
        method="restyle",
        args=["visible", [False] * len(fig.data)],
    )
    step["args"][1][i] = True  # Toggle i'th trace to "visible"
    steps.append(step)

sliders = [dict(
    active=10,
    currentvalue={"prefix": "Frequency: "},
    pad={"t": 50},
    steps=steps
)]

fig.update_layout(
    sliders=sliders
)

plotly.offline.plot(fig, filename='plotly_slider.html', auto_open=True)

np.eye()

協方差矩陣, 如 eye(3) 產生3*3維矩陣,  中心對角為均為 1

a=np.eye(3)
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

eye(3, k=1), 右上第一條對角線為 1

[[0. 1. 0.]
 [0. 0. 1.]
 [0. 0. 0.]]

eye(3, k=-1), 左下第一條對角線為 1

[[0. 0. 0.]
 [1. 0. 0.]
 [0. 1. 0.]]

np.random.multivariate_normal

此方法用於產生多元正態分佈矩陣, 裏面共有三個參數(多維分佈均值, 協方差矩陣, 組數)

第一個參數 np.array([0,0,0]) : 產生三個亂數, 每個亂數的平均值為 0. 若為([1,1,1]), 則其平均值為1.
第二個參數為 eye(n), 產生 n*n的對角陣列.
第三個參數為產生幾組亂數.

以下會產生100組三個元素的陣列, 若再加上 transpose(), 則會90度旋轉, 產生三組 list

import numpy as np
a=np.random.multivariate_normal(np.array([0,0,0]), np.eye(3), 100)
print(a)
print(a.transpose())
結果:
[[ 0.52644838 -0.54311624 1.07767445]
 [ 0.75128152 -0.72321168 -0.50488629]]
[[ 0.52644838 0.75128152]
 [-0.54311624 -0.72321168]
 [ 1.07767445 -0.50488629]]

簡易3D點散圖 Scatter3d

首先使用np產生三組亂數list, 作為x, y, z的值, 再使用 go.Scatter3d繪製圖型 trace1, trace2. 然後將所有圖形加入list中, 並設定layout邊界, 然後將list及layout交給offline顯圖

請注意

1. 官方及網路上的教學, 都以 如下方式繪圖, 但這是給 jupyter notebook用的. 使用Pycharm, 則需使用plot.offline.plot進行繪圖

import plotly.plotly as py
py.iplot(fig, filename='simple-3d-scatter')

2.  color=’rgba(255,0,0,0.5)’, 其 alpha不是 0~255, 而是0~1,愈大愈不透明

底下的繪圖步驟為
a. 使用 go.Scatter3d()產生trace資料
b. 再將所有的trace集合成一個 list, (在此以data變數命名)
c. 使用 go.Figure產生圖表. go.Figure裏的參數即為data, 並再多加一個layout的設置
d. 最後使用 plotly.offline.plot將圖表繪出

#!/usr/bin/python3
import plotly.graph_objs as go
import plotly
import numpy as np

x, y, z = np.random.multivariate_normal(np.array([0,0,0]), np.eye(3), 20).transpose()
trace1 = go.Scatter3d(
    x=x,
    y=y,
    z=z,
    mode='markers',
    marker=dict(
        size=12,
        line=dict(color='rgba(217, 217, 217, 0.14)',width=0.5),
        opacity=0.8
    )
)

x2, y2, z2 = np.random.multivariate_normal(np.array([0,0,0]), np.eye(3), 20).transpose()
trace2 = go.Scatter3d(
    x=x2,
    y=y2,
    z=z2,
    mode='markers',
    marker=dict(
        color='rgba(255, 0, 0, 0.5)',
        size=12,
        symbol='circle',
        line=dict(color='rgb(204, 204, 204)',width=1),
        opacity=0.9
    )
)
data = [trace1, trace2]
layout = go.Layout(
    margin=dict(
        l=0,
        r=0,
        b=0,
        t=0
    )
)
fig = go.Figure(data=data, layout=layout)
plotly.offline.plot(fig, filename='plotly3d_simple.html', auto_open=True)

Color Scaling

要畫出鮮豔的色彩其實很簡單, 只需更改如下藍色的地方即可

viridis[՝viridis] : 翠綠色

#!/usr/bin/python3
import plotly.graph_objs as go
import plotly
import numpy as np

x, y, z = np.random.multivariate_normal(np.array([0,0,0]), np.eye(3), 300).transpose()
trace1 = go.Scatter3d(
    x=x,
    y=y,
    z=z,
    mode='markers',
    marker=dict(
        size=12,
        color=z,
        colorscale='Viridis',
        line=dict(color='rgba(217, 217, 217, 0.14)',width=0.5),
        opacity=0.8
    )
)

data = [trace1]
layout = go.Layout(
    margin=dict(
        l=0,
        r=0,
        b=0,
        t=0
    )
)
fig = go.Figure(data=data, layout=layout)
plotly.offline.plot(fig, filename='plotly3d_colorscale.html', auto_open=True)

直線

底下是畫直線的方式. 而繪圖步驟也不一定要按上面所描述.
a. 使用go.Figure()產生圖表
b. 產生trace. 並使用 fig.add_trace()將 trace加入
c. 產生layout, 並使用 fig.update_layout將layout加入
d. plotly.offline.plot將圖表繪出

#!/usr/bin/python3
import plotly.graph_objs as go
import plotly
import numpy as np

x=np.zeros(20)
y=np.zeros(20)
z=list(range(20))
fig=go.Figure()
fig.add_trace(
    go.Scatter3d(
        x=x, y=y, z=z, mode='markers+lines',
        marker=dict(
            size=8,
            line=dict(color='rgba(0, 0, 0, 0)',width=0),
            color='rgba(255, 0, 255, 0.5)',
        )
    )
)
fig.update_layout(
    go.Layout(
        margin=dict(l=0,r=0,b=0,t=0)
    )
)
plotly.offline.plot(fig, filename='plotly3d_line.html', auto_open=True)

歐幾里得

歐幾里得公式就是直角三角形的斜邊是二邊長的平方總和開根號

$(r=\sqrt{x^2+y^2})$

但歐幾里得的精華並不是只有如此而以,三維的直線距離如下

$(z=\sqrt{x^2+y^2+z^2})$

請由如下的代碼及圖示,仔細思考一下。

import plotly.graph_objs as go
import plotly
import numpy as np
px=20
py=15
pz=6
trace_axis_x=go.Scatter3d(
    x=[0,px+2],
    y=[0,0],
    z=[0,0],
    mode='lines',
    line=dict(color='rgb(0,0,0)', width=1),
)

trace_axis_y=go.Scatter3d(
    x=[0,0],
    y=[0,px+2],
    z=[0,0],
    mode='lines',
    line=dict(color='rgb(0,0,0)', width=1),
)

trace_axis_z=go.Scatter3d(
    x=[0,0],
    y=[0,0],
    z=[0,pz+2],
    mode='lines',
    line=dict(color='rgb(0,0,0)', width=1),
)
trace_r=go.Scatter3d(
    x=[0,px],
    y=[0,py],
    z=[0,pz],
    mode='markers+lines+text',
    text=["(0,0,0)","(20,15,10)"],
    line=dict(color='rgb(0,0,255)', width=10),
)

trace_r_text=go.Scatter3d(
    x=[px/2],
    y=[py/2],
    z=[pz/2-0.2],
    mode='text',
    text=["r"],
)

trace_x=go.Scatter3d(
    x=[px,0],
    y=[0,0],
    z=[0,0],
    mode='lines',
    line=dict(color='rgb(0,255,0)', width=5),
)
trace_x_text=go.Scatter3d(
    x=[(px+2)/2],
    y=[0.5],
    z=[0],
    mode='text',
    text=["x"]
)
trace_y=go.Scatter3d(
    x=[px,px],
    y=[py,0],
    z=[0,0],
    mode='lines',
    line=dict(color='rgb(0,255,255)', width=5),
)
trace_y_text=go.Scatter3d(
    x=[px],
    y=[(py+2)/2],
    z=[0],
    mode='text',
    text=["Y"]
)

trace_m=go.Scatter3d(
    x=[px,0],
    y=[py,0],
    z=[0,0],
    mode='lines',
    line=dict(color='rgb(255,0,255)', width=5),
)

trace_m_text=go.Scatter3d(
    x=[px/2],
    y=[py/2],
    z=[0],
    mode='text',
    text=["m"]
)

trace_z=go.Scatter3d(
    x=[px,px],
    y=[py,py],
    z=[0,pz],
    mode='lines',
    line=dict(color='rgb(255,255,0)', width=5),
)
trace_z_text=go.Scatter3d(
    x=[px-0.2],
    y=[py-0.2],
    z=[pz/2],
    mode='text',
    text=["z"],
)
layout = go.Layout(
    margin=dict(
        l=0,
        r=0,
        b=0,
        t=0
    ),
    scene = dict(
        xaxis=dict(nticks=6, range=[0, px+2],showticklabels=False, title=""),
        yaxis=dict(nticks=6, range=[0, py+2],showticklabels=False, title=""),
        zaxis=dict(nticks=6, range=[0, pz+2],showticklabels=False, title="")
    ),
    showlegend=False,
    font=dict(size=14),
    scene_camera = dict(
        up=dict(x=0, y=0, z=1),
        center=dict(x=0, y=0, z=0),
        eye=dict(x=0.3, y=2, z=0.5)
    )
)

data=[trace_axis_y,
      trace_axis_y,
      trace_axis_z,
      trace_x,
      trace_y,
      trace_z,
      trace_m,
      trace_r,
      trace_x_text,
      trace_y_text,
      trace_z_text,
      trace_m_text,
      trace_r_text]
fig=go.Figure(data=data, layout=layout)
plotly.offline.plot(fig, filename="euclid.html", auto_open=True)

圖形如下

由上圖可知 $(m=\sqrt{x^2+y^2})$。

$(r=\sqrt{m^2+z^2}=\sqrt{x^2+y^2+z^2})$

能在網頁上畫出三維的解說,本站也算是先進了吧。

那麼 4,5 維呢? 這就無法用圖示畫出來了。但由上述說明,公式就是

$(r=\sqrt{x_{1}^2+x_{2}^2+x_{3}^2+x_{4}^2+x_{5}^2})$

$(x_{1}, x_{2}, x_{3}, x_{4}, x_{5})$ 分別代表不同的變數,也就多個維度。

圓型

底下範例,繪製 10 個圓型

#!/usr/bin/python3
import random
import plotly.graph_objs as go
import plotly
import numpy as np
r=100
a=np.linspace(0,360,360)
x=r*np.cos(a*np.pi/180)
y=r*np.sin(a*np.pi/180)
z=np.ones([360])
data=[]
for i in range(0, 100, 10):
    trace=go.Scatter3d(
        x=x,
        y=y,
        z=z*i,
        mode='lines',
        line=dict(color=f'rgb({random.randint(0,255)},{random.randint(0,255)},{random.randint(0,255)})', width=10),
    )
    data.append(trace)

layout = go.Layout(
    margin=dict(
        l=0,
        r=0,
        b=0,
        t=0
    )
)
fig=go.Figure(data=data, layout=layout)
fig.show()
plotly.offline.plot(fig, filename="circle.html",auto_open=False)

螺旋

#!/usr/bin/python3
import plotly.graph_objs as go
import plotly
import numpy as np
r=100
n=360*10
a=np.linspace(0,n,n)
x=r*np.cos(a*np.pi/180)
y=r*np.sin(a*np.pi/180)
z=list(range(n))

trace = go.Scatter3d(
    x=x,
    y=y,
    z=z,
    mode='lines',
    line=dict(color='rgba(0,0,255,1)', width=10),
)
data=[trace]
layout = go.Layout(
    margin=dict(
        l=0,
        r=0,
        b=0,
        t=0
    )
)

fig=go.Figure(data=data, layout=layout)
plotly.offline.plot(fig, auto_open=True)

台灣股市

先使用go.Figure產生Figure物件,然後再用fig.add_trace產生路徑

import mysql.connector as mysql
import pandas as pd
import plotly_express as px
import plotly
import plotly.graph_objects as go
import numpy as np
conn = mysql.connect(host='ip', user='帳號', password='密碼', database='資料庫')
cursor = conn.cursor()
cmd = "select * from taiex where tx_date>'2021-01-01' order by tx_date"
cursor.execute(cmd)
rs = cursor.fetchall()
cursor.close()
conn.close()
ls = [r for r in rs]
cols = ['id', '日期', 'openning', 'highest', 'lowest', '收盤價']
df = pd.DataFrame(ls, columns=cols)
fig=go.Figure()
fig.add_trace(go.Scatter(x=df['日期'], y=df['收盤價'], line=dict(color='blue', width=2), showlegend=False))
x=list(range(len(rs)))
f=np.poly1d(np.polyfit(x, df['收盤價'],20))
reg=f(x)
fig.add_trace(go.Scatter(x=df['日期'], y=reg, name='迴歸線',line=dict(color='red', width=2)))
fig.update_layout(title='台灣股市')
fig.show()

Fill Line

#!/usr/bin/python3
import plotly
import pandas as pd
import plotly.graph_objs as go
url_csv = 'http://www.stat.ubc.ca/~jenny/notOcto/STAT545A/examples/gapminder/data/gapminderDataFiveYear.txt'
df = pd.read_csv(url_csv, sep='\t')
for c in df:
    print('%s\t' %c, end='')
print()
for i in range(df.shape[0]):
    for j in range(df.shape[1]):
        print('%s\t' % df.iloc[i][j], end='')
    print()

countries = ['China', 'India', 'United States', 'Bangladesh', 'South Africa']
fill_colors = ['#66c2a5', '#fc8d62', '#8da0cb', '#e78ac3', '#a6d854']
gf = df.groupby('country')

data = []

for country, fill_color in zip(countries[::-1], fill_colors):
    group = gf.get_group(country)
    years = group['year'].tolist()
    length = len(years)
    country_coords = [country] * length
    pop = group['pop'].tolist()
    zeros = [0] * length

    trace=go.Scatter3d(
        mode='lines',
        x=years + years[::-1] + [years[0]],  # year loop: in incr. order then in decr. order then years[0]
        y=country_coords * 2 + [country_coords[0]],
        z=pop + zeros + [pop[0]],
        name='',
        surfaceaxis=1,  # add a surface axis ('1' refers to axes[1] i.e. the y-axis)
        surfacecolor=fill_color,
        line=dict(
            color='black',
            width=4
        )
    )
    data.append(trace)

layout = dict(
    title='Population from 1957 to 2007 [Gapminder]',
    showlegend=False,
    scene=dict(
        xaxis=dict(title=''),
        yaxis=dict(title=''),
        zaxis=dict(title=''),
        camera=dict(
            eye=dict(x=-1.7, y=-1.7, z=0.5)
        )
    )
)
fig=go.Figure(data=data, layout=layout)
plotly.offline.plot(fig, filename='plotly3d_fillline.html', auto_open=True)

3D地型圖

Topographical [͵tɑpəˋgræfɪk!]

地型圖是一個非常厲害的演算法, 只需要x, y平面中, 將每一點的Z軸高度傳入, 就可以在3D空間中取得各點之間的曲線. 下面的代碼中, 使用pd.read_csv()讀取官網的範例資料. 在此本人額外加入了 dtype=’str’, 將讀取的資料直接以字串讀取, 讓列印出來的小數值不會因精準度而亂跳.

最後將讀取的軸z高度傳入go.Surface()

import plotly.graph_objects as go
import plotly
import pandas as pd

pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
pd.set_option('display.width', None)
pd.set_option('display.max_colwidth', None)

# Read data from a csv
df = pd.read_csv(
'https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv', 
dtype='float')
print(df)
trace=go.Surface(z=df.values) # 將dataframe所有的值以list列出
data=[trace]
layout=go.Layout(title='Mt Bruno Elevation', autosize=True,
                  margin=dict(l=50, r=50, b=50, t=50))
fig = go.Figure(data=data, layout=layout)
fig.show()
plotly.offline.plot(fig, filename='plotly3d_Topographical.html', auto_open=False )
結果:
    Unnamed: 0          0           1           2          3          4          5          6          7          8          9         10         11         12         13          14         15          16          17          18         19          20         21         22         23
0          0.0  27.809850   49.619360   83.080670  116.66320  130.41400  150.72060  220.18710  156.15360  148.64160  203.78450  206.03860  107.16180   68.36975   45.33590   49.961420   21.89279   17.025520   11.743170   14.752260  13.667100    5.677561   3.312340   1.156517  -0.147662
1          1.0  27.719660   48.550220   65.213740   95.27666  116.99640  133.90560  152.34120  151.93400  160.11390  179.53270  147.61840  170.39430  121.81940   52.58537   33.088710   38.40972   44.248430   69.578600    4.019351   3.050024    3.039719   2.996142   2.967954   1.999594
2          2.0  30.426700   33.477520   44.809530   62.47495   77.43523  104.21530  102.73930  137.00040  186.07060  219.31730  181.76150  120.91540  143.18350   82.40501   48.471320   74.71461   60.090900    7.073525    6.089851   6.537450    6.666096   7.306965   5.736840   3.625628
3          3.0  16.665490   30.108600   39.969520   44.12225   59.57512   77.56929  106.89250  166.55390  175.23810  185.28150  154.50560   83.04330   62.61732   62.33167   60.559160   55.92124   15.172840    8.248324   36.680870  61.934130   20.268670  68.588190  46.498120   0.236010
4          4.0   8.815617   18.351600    8.658275   27.58590   48.62691   60.18013   91.32860  145.71090  116.06530  106.26620   68.69447   53.10596   37.92797   47.95942   47.426910   69.20731   44.954680   29.171970   17.916740  16.255150   14.655590  17.260480  31.222450  46.717040
5          5.0   6.628881   10.413390   24.819390   26.08952   30.16050   52.30802   64.71007   76.30823   84.63686   99.43240   62.52132   46.81647   55.76606   82.40990  140.264700   81.26501   56.457560   30.421640   17.287820   8.302431    2.981626   2.698536   5.886086   5.268358
6          6.0  21.839750    6.639270   18.970850   32.89204   43.15014   62.86014  104.66570  130.22940  114.84940  106.98730   61.89647   55.55682   86.80986   89.27802  122.422100  123.96980  109.095200   98.419560   77.613740  32.490310   14.673440   7.370775   0.037110   0.642339
7          7.0  53.343030   26.797970    6.639270   10.88787   17.20440   56.18116   79.70141   90.84530   98.27675   80.87243   74.79310   75.54661   73.43730   74.11694   68.174900   46.24076   39.938570   31.216530   36.883350  40.025250  117.429700  12.703280   1.729771   0.000000
8          8.0  25.667850   63.057170   22.141400   17.07400   41.74483   60.27227   81.42432  114.44400  102.32340  101.78780  111.03100  119.23090  114.07770  110.52960   59.193550   42.47175   14.635980    6.944074    6.944075  27.749360    0.000000   0.000000   0.094494   0.077323
9          9.0  12.827000   69.205540   46.762930   13.96517   33.88744   61.82613   84.74799  121.12200  145.27410  153.17970  204.78600  227.92420  236.30380  228.36550   79.344250   25.93483    6.944074    6.944074    6.944075   7.553681    0.000000   0.000000   0.000000   0.000000
10        10.0   0.000000   68.663960   59.043500   33.35762   47.45282   57.83550   78.91689  107.82750  168.00530  130.95970  212.55410  165.81220  210.24290  181.17130  189.761700  137.33780   84.653950    8.677168    6.956576   8.468093    0.000000   0.000000   0.000000   0.000000
11        11.0   0.000000   95.174990   80.038180   59.89862   39.58476   50.28058   63.81641   80.61302   66.37824  198.76510  244.34670  294.24740  264.35170  176.40820   60.218570   77.41475   53.169810   56.163930    6.949235   7.531059    3.780177   0.000000   0.000000   0.000000
12        12.0   0.000000  134.987900  130.369600   96.86325   75.70494   58.86466   57.20374   55.18837   78.12800  108.55820  154.37740  319.16860  372.88260  275.46550  130.263200   54.93822   25.497190    8.047439    8.084393   5.115252    5.678269   0.000000   0.000000   0.000000
13        13.0   0.000000   48.089190  142.555800  140.37770  154.72610   87.93610   58.11092   52.83869   67.14822   83.66798  118.92420  150.06810  272.97090  341.13660  238.664000  190.20000  116.894300   91.486720   14.015700  42.292770    5.115252   0.000000   0.000000   0.000000
14        14.0   0.000000   54.194100  146.383900   99.48143   96.19411  102.94730   76.14089   57.78440   47.04020   64.36799   84.23767  162.71810  121.32750  213.16460  328.482000  285.44890  283.831900  212.815000  164.549000  92.296310    7.244015   1.167000   0.000000   0.000000
15        15.0   0.000000    6.919659  195.170900  132.52530  135.23410   89.85069   89.45549   60.29967   50.33806   39.17583   59.06854   74.52159   84.93402  187.12190  123.967300  103.70270  128.986000  165.128300  249.705400  95.399660   10.002840   2.392550   0.000000   0.000000
16        16.0   0.000000   21.738710  123.133900  176.74140  158.26980  137.23500  105.30890   86.63255   53.11591   29.03865   30.40539   39.04902   49.23405   63.27853  111.421500  101.19560   40.009620   59.845650   74.512530  17.063160    2.435141   2.287471  -0.000364   0.000000
17        17.0   0.000000    0.000000   62.046720  136.31220  201.79520  168.13430   95.20460   58.90624   46.94091   49.27053   37.10416   17.97011   30.93697   33.39257   44.030770   55.64542   78.224230   14.427820    9.954997   7.768213   13.025400  21.731660   2.156372   0.531787
18        18.0   0.000000    0.000000   79.629930  139.69780  173.16700  192.87180  196.34990  144.66110  106.54240   57.16653   41.16107   32.12764   13.85660   10.91772   12.071770   22.38254   24.721050    6.803666    4.200841  16.468570   15.707440  33.962210   7.575688  -0.048809
19        19.0   0.000000    0.000000   33.266400   57.53643  167.22410  196.48330  194.79660  182.18840  119.69610   73.02113   48.36549   33.74652   26.23790   16.35780    6.811293    6.63927    6.639271    8.468093    6.194273   3.591233    3.814860   8.600739   5.218890   0.000000
20        20.0   0.000000    0.000000   29.779370   54.97282  144.79950  207.49040  165.34320  171.40470  174.92160  100.27330   61.46441   50.19171   26.08209   17.18218    8.468093    6.63927    6.334467    6.334467    5.666687   4.272203    0.000000   0.000000   0.000000   0.000000
21        21.0   0.000000    0.000000   31.409000  132.74180  185.57960  121.82990  185.38410  160.65660  116.14780  118.10780  141.79460   65.56351   48.84066   23.13864   18.129320   10.28531    6.029663    6.044627    5.694764   3.739085    3.896037   0.000000   0.000000   0.000000
22        22.0   0.000000    0.000000   19.589940   42.30355   96.26777  187.12070  179.66260  221.38980  154.26170  142.16040  148.57370   67.17937   40.69044   39.74512   26.101660   14.48469    8.658730    3.896037    3.571392   3.896037    3.896037   3.896037   1.077756   0.000000
23        23.0   0.001230    3.008948    5.909858   33.50574  104.33410  152.21650  198.19880  191.84100  228.73490  168.10410  144.27590  110.74360   57.65214   42.63504   27.918910   15.41052    8.056102    3.902830    3.879774   3.936718    3.968634   0.123626   3.985531  -0.183574
24        24.0   0.000000    5.626141    7.676256   63.16226   45.99762   79.56688  227.31100  203.92870  172.56180  177.14620  140.45540  123.99050  110.34600   65.12319   34.318870   24.52780    9.561069    3.334991    5.590495   5.487353    5.909499   5.868994   5.833817   3.568177

其他支援

plotly目前長條圖, 圓餅圖等, 並沒有3D支援. 官方說明了未來可能會支援, 但不在短期之內. 也就是說未來一年內, 都不會推出其他3D的圖形

官網

官方網址有些教學簡介,請參考如下 : https://plot.ly/python/3d-surface-plots/

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *