Simple Slider Control
#!/usr/bin/python3 import plotly.graph_objects as go import numpy as np import plotly # Create figure fig = go.Figure() x=np.arange(0, 10, 0.01) # 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=x, y=np.sin(step * x) ) ) # 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 ) fig.show() #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)
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/