<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>BOKEH &#8211; FinLab</title>
	<atom:link href="https://www.finlab.tw/tag/bokeh/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.finlab.tw</link>
	<description>深入淺出的量化投資，讓你在在茫茫股海中，找到專屬於自己的投資方法</description>
	<lastBuildDate>Tue, 28 Jul 2020 06:55:03 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.0.9</generator>

<image>
	<url>https://www.finlab.tw/wp-content/uploads/2020/07/favicon.png</url>
	<title>BOKEH &#8211; FinLab</title>
	<link>https://www.finlab.tw</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">179699571</site>	<item>
		<title>Bokeh 探索頻道(1)~Python互動式圖表函數庫初體驗</title>
		<link>https://www.finlab.tw/python-bokeh1-setup-and-first-impression/</link>
					<comments>https://www.finlab.tw/python-bokeh1-setup-and-first-impression/#respond</comments>
		
		<dc:creator><![CDATA[Ben]]></dc:creator>
		<pubDate>Mon, 20 Jul 2020 12:02:48 +0000</pubDate>
				<category><![CDATA[財經PYTHON教學]]></category>
		<category><![CDATA[BOKEH]]></category>
		<category><![CDATA[PYTHON]]></category>
		<category><![CDATA[資料視覺化]]></category>
		<guid isPermaLink="false">http://34.96.136.135/?p=1120</guid>

					<description><![CDATA[Python 視覺化套件使用經驗

Python套件多，品質不一。用module之前，我習慣先看github星星確認認可度，有1000個以上多是品質保證，再看release history，看是否有被持續維護，那種2年以上沒新版本的，採坑機率高。Bokeh看來沒問題。]]></description>
										<content:encoded><![CDATA[
<h3 id="Python-視覺化套件使用經驗">Python 視覺化套件使用經驗</h3>



<p>Python套件多，品質不一。用module之前，我習慣先看github星星確認認可度，有1000個以上多是品質保證，再看release history，看是否有被持續維護，那種2年以上沒新版本的，採坑機率高。Bokeh看來沒問題。</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img width="1024" height="246" src="http://34.96.136.135/wp-content/uploads/2020/07/y3p5KBo-1024x246.png" alt="y3p5KBo" class="wp-image-1121" srcset="https://www.finlab.tw/wp-content/uploads/2020/07/y3p5KBo-1024x246.png 1024w, https://www.finlab.tw/wp-content/uploads/2020/07/y3p5KBo-300x72.png 300w, https://www.finlab.tw/wp-content/uploads/2020/07/y3p5KBo-768x185.png 768w, https://www.finlab.tw/wp-content/uploads/2020/07/y3p5KBo-1536x369.png 1536w, https://www.finlab.tw/wp-content/uploads/2020/07/y3p5KBo.png 2046w" sizes="(max-width: 1024px) 100vw, 1024px" title="Bokeh 探索頻道(1)~Python互動式圖表函數庫初體驗 1"></figure></div>



<p>平常python視覺化的主力套件是matplotlib和seaborn，前者是20歲老套件，是視覺化元祖，許多套件基礎都是建構在matplotlib上，像seaborn就是，有更簡潔的寫法和精美圖例，兩者都以靜態視覺居多，缺乏變化性(或是要費點功)。<br>Python守備範圍廣，但在網頁前端仍難以與Java Script抗衡，而D3.js函數庫也要花不少學習成本，有沒有辦法用Python做出JS動態視覺的效果？</p>



<p>Bokeh的出世，提供了Python與D3.js之間的橋梁，讓你可以用Python做出D3.js常用功能的效果，減少學習成本，高效開發，輕鬆描述統計結果。</p>



<h3 id="厲害在哪裡？">厲害在哪裡？</h3>



<p>先來看Gallory，python視覺化套件很多，範例圖不夠精美的，可考慮跳過。</p>



<ol><li>化學元素週期表</li></ol>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="1024" height="459" src="http://34.96.136.135/wp-content/uploads/2020/07/81XiMAU-1-1024x459.png" alt="81XiMAU 1" class="wp-image-1123" srcset="https://www.finlab.tw/wp-content/uploads/2020/07/81XiMAU-1-1024x459.png 1024w, https://www.finlab.tw/wp-content/uploads/2020/07/81XiMAU-1-300x134.png 300w, https://www.finlab.tw/wp-content/uploads/2020/07/81XiMAU-1-768x344.png 768w, https://www.finlab.tw/wp-content/uploads/2020/07/81XiMAU-1-1536x688.png 1536w, https://www.finlab.tw/wp-content/uploads/2020/07/81XiMAU-1-2048x918.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" title="Bokeh 探索頻道(1)~Python互動式圖表函數庫初體驗 2"></figure></div>



<ol start="2"><li>雷達圖</li></ol>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="1024" height="1000" src="http://34.96.136.135/wp-content/uploads/2020/07/hMPxBgq-1-1024x1000.png" alt="hMPxBgq 1" class="wp-image-1125" srcset="https://www.finlab.tw/wp-content/uploads/2020/07/hMPxBgq-1-1024x1000.png 1024w, https://www.finlab.tw/wp-content/uploads/2020/07/hMPxBgq-1-300x293.png 300w, https://www.finlab.tw/wp-content/uploads/2020/07/hMPxBgq-1-768x750.png 768w, https://www.finlab.tw/wp-content/uploads/2020/07/hMPxBgq-1.png 1422w" sizes="(max-width: 1024px) 100vw, 1024px" title="Bokeh 探索頻道(1)~Python互動式圖表函數庫初體驗 3"></figure></div>



<ol start="3"><li>互動式wiget散點圖表</li></ol>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="1024" height="613" src="http://34.96.136.135/wp-content/uploads/2020/07/9vnv8yZ-1-1024x613.png" alt="9vnv8yZ 1" class="wp-image-1127" srcset="https://www.finlab.tw/wp-content/uploads/2020/07/9vnv8yZ-1-1024x613.png 1024w, https://www.finlab.tw/wp-content/uploads/2020/07/9vnv8yZ-1-300x179.png 300w, https://www.finlab.tw/wp-content/uploads/2020/07/9vnv8yZ-1-768x459.png 768w, https://www.finlab.tw/wp-content/uploads/2020/07/9vnv8yZ-1-1536x919.png 1536w, https://www.finlab.tw/wp-content/uploads/2020/07/9vnv8yZ-1-2048x1225.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" title="Bokeh 探索頻道(1)~Python互動式圖表函數庫初體驗 4"></figure></div>



<p>逛了一圈，發現Bokeh圖表精美、範例多、都有附原始碼，官方教學也完整，有tutorial jupyter檔案教學。<br>看來比matplotlib強大，也比plotly漂亮…，函數庫使用看來也不難，且可鑲嵌到Django等Web框架，無論是local或遠端的前端呈現都可以效率開發。</p>



<h3 id="開箱試玩時間">開箱試玩時間</h3>



<p>要注意的是bokeh會預設連BokehJS cdn，但連線有時不是很穩定，這時可多加”INLINE”環境變數設定，讓BokehJS驅動於local python env。</p>



<pre class="wp-block-code"><code class="">from bokeh.resources import INLINE
bokeh.io.output_notebook(INLINE)</code></pre>



<p>Bokeh可以在Jupyter呈現開發也可以跳轉出html檔，可自由設定，預設是跳轉html檔(output_file())。若要更改預設，必須加上<code>bokeh.io.reset_output()</code>重設環境預設。</p>



<pre class="wp-block-code"><code class="">output_notebook() ＃jupyter呈現
output_file()  ＃html呈現</code></pre>



<p>fig物件可設定tools參數，圖表會自帶縮放、重整、儲存等功能。<br>以下是參考官方範例後微調的程式。</p>



<pre class="wp-block-code"><code class="">from bokeh.plotting import figure, output_file, show, output_notebook
import bokeh.io
from bokeh.resources import INLINE

# env settings 環境變數設定
bokeh.io.reset_output()
bokeh.io.output_notebook(INLINE)

# prepare some data
x = [0.1, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]
y0 = [i**2 for i in x]
y1 = [10**i for i in x]
y2 = [10**(i**2) for i in x]

# output to static HTML file
# output_file("log_lines.html")

# create a new plot
p = figure(
tools="pan,box_zoom,reset,save",
y_axis_type="log", y_range=[0.001, 10**11], title="log axis example",
x_axis_label='sections', y_axis_label='particles'
)

# add some renderers
p.line(x, x, legend_label="y=x")
p.circle(x, x, legend_label="y=x", fill_color="white", size=8)
p.line(x, y0, legend_label="y=x^2", line_width=3)
p.line(x, y1, legend_label="y=10^x", line_color="red")
p.circle(x, y1, legend_label="y=10^x", fill_color="red", line_color="red", size=6)
p.line(x, y2, legend_label="y=10^x^2", line_color="orange", line_dash="4 4")

# show the results
show(p)
output_notebook() </code></pre>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="1024" height="717" src="http://34.96.136.135/wp-content/uploads/2020/07/cK9ZFBB-1024x717.png" alt="cK9ZFBB" class="wp-image-1128" srcset="https://www.finlab.tw/wp-content/uploads/2020/07/cK9ZFBB-1024x717.png 1024w, https://www.finlab.tw/wp-content/uploads/2020/07/cK9ZFBB-300x210.png 300w, https://www.finlab.tw/wp-content/uploads/2020/07/cK9ZFBB-768x538.png 768w, https://www.finlab.tw/wp-content/uploads/2020/07/cK9ZFBB.png 1453w" sizes="(max-width: 1024px) 100vw, 1024px" title="Bokeh 探索頻道(1)~Python互動式圖表函數庫初體驗 5"></figure></div>



<h3 id="投資圖表試玩">投資圖表試玩</h3>



<p>Bokeh官方有提供sample_data給大家練習，gallery豐富的範例都取自sample_data，對比官方的資料格式就能輕鬆模仿應用，沒啥高深程式技巧。下載sample_data指令為<code>bokeh.sampledata.download()</code>，直接貼在jupyter執行。檔案會下載到bokeh module裡。</p>



<h3 id="檢查蘋果電腦範例資料-json">檢查蘋果電腦範例資料(json)</h3>



<pre class="wp-block-code"><code class="">from bokeh.sampledata.stocks import AAPL
# 檢查欄位
AAPL.keys()
#dict_keys(['date', 'open', 'high', 'low', 'close', 'volume', 'adj_close'])</code></pre>



<h3 id="ColumnDataSource物件為Bokeh資料驅動渲染核心">ColumnDataSource物件為Bokeh資料驅動渲染核心</h3>



<p>dataframe要傳入ColumnDataSource才能驅動js。<br>providing the data that is visualized by the glyphs of the plot<br><a href="https://docs.bokeh.org/en/latest/docs/user_guide/data.html" rel="noreferrer noopener" target="_blank">https://docs.bokeh.org/en/latest/docs/user_guide/data.html</a></p>



<h3 id="HoverTool">HoverTool</h3>



<p>游標滑過時顯示資料</p>



<h3 id="Click-policy">Click_policy</h3>



<p>藉由標籤控制數值顯示<br>hide為隱藏，mute為切換自訂顯示模式<br>可在muted_color控制顏色, muted_alpha控制顏色濃淡</p>



<h3 id="程式範例">程式範例</h3>



<pre class="wp-block-code"><code class="">
import bokeh.io
from bokeh.resources import INLINE
from bokeh.models import HoverTool
from bokeh.palettes import Spectral4
from bokeh.plotting import figure, output_file, show, output_notebook, ColumnDataSource
from bokeh.sampledata.stocks import AAPL, GOOG, IBM, MSFT
import pandas as pd

# env settings
bokeh.io.reset_output()
bokeh.io.output_notebook(INLINE)


# set hover
## HoverTool
# 游標滑過時顯示資料,date格式需要轉換，不然會是timestamp
hover = HoverTool(
    tooltips = [
        ("date", "@date"),
        ("close", "@open"),
        ("close", "@close"),
        ("high", "@high"),
        ("low", "@low"),
        ("volume","@volume")
    ], 
    formatters={"@date":"datetime"}
)

# set figure
p = figure(
    plot_width=1000, 
    plot_height=400, 
    x_axis_type="datetime",
    tools=[hover,"pan,box_zoom,reset,save"],
)
p.title.text = 'Stock_Price--Click on legend entries to mute the corresponding lines and show daily details in hover'

# use ColumnDataSource to control
# click_policy
# 藉由標籤控制數值顯示
# hide為隱藏，mute為切換自訂顯示模式
# 可在muted_color控制顏色, muted_alpha控制顏色濃淡

for data, name, color in zip([AAPL, IBM, MSFT, GOOG], ["AAPL", "IBM", "MSFT", "GOOG"], Spectral4):
    df = pd.DataFrame(data)
    df['date'] = pd.to_datetime(df['date'])
    source = ColumnDataSource(df)
    p.line(x="date",y="close", line_width=2, color=color, alpha=0.8,
           muted_color=color, muted_alpha=0.2, legend_label=name,source=source)


p.legend.location = "top_left"
# use hide or mute
p.legend.click_policy="mute"

# output_file("interactive_legend.html", title="interactive_legend.py example")

show(p)
output_notebook() </code></pre>



<h3 id="兩種模式結果比較">兩種模式結果比較</h3>



<ol><li>Mute</li></ol>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="1024" height="445" src="http://34.96.136.135/wp-content/uploads/2020/07/xkQhfUt-1024x445.png" alt="xkQhfUt" class="wp-image-1129" srcset="https://www.finlab.tw/wp-content/uploads/2020/07/xkQhfUt-1024x445.png 1024w, https://www.finlab.tw/wp-content/uploads/2020/07/xkQhfUt-300x130.png 300w, https://www.finlab.tw/wp-content/uploads/2020/07/xkQhfUt-768x334.png 768w, https://www.finlab.tw/wp-content/uploads/2020/07/xkQhfUt-1536x667.png 1536w, https://www.finlab.tw/wp-content/uploads/2020/07/xkQhfUt.png 1706w" sizes="(max-width: 1024px) 100vw, 1024px" title="Bokeh 探索頻道(1)~Python互動式圖表函數庫初體驗 6"></figure></div>



<p>       2.  Hide</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="1024" height="456" src="http://34.96.136.135/wp-content/uploads/2020/07/fKmVrH1-1-1024x456.png" alt="fKmVrH1 1" class="wp-image-1131" srcset="https://www.finlab.tw/wp-content/uploads/2020/07/fKmVrH1-1-1024x456.png 1024w, https://www.finlab.tw/wp-content/uploads/2020/07/fKmVrH1-1-300x134.png 300w, https://www.finlab.tw/wp-content/uploads/2020/07/fKmVrH1-1-768x342.png 768w, https://www.finlab.tw/wp-content/uploads/2020/07/fKmVrH1-1-1536x684.png 1536w, https://www.finlab.tw/wp-content/uploads/2020/07/fKmVrH1-1.png 1746w" sizes="(max-width: 1024px) 100vw, 1024px" title="Bokeh 探索頻道(1)~Python互動式圖表函數庫初體驗 7"></figure></div>



<h3 id="小結">小結</h3>



<p>這篇主要是來體會一下Bokeh的效果，不用會JS，隨便玩就有這種效果，蠻滿意的，值得再深入一下細節，把以前matplotlib的圖表都轉來bokeh，無論是在工作上的資料報告還是看盤需要，都蠻方便的。</p>



<p>假如想要進一步學習 Bokeh，我將會分享一系列文章，來介紹 Bokeh 在投資領域的視覺化喔！<br><a href="https://www.finlab.tw/python-bokeh1-setup-and-first-impression/bokeh-stock-chart-with-technical-analysis">下一篇文章，帶你繪製專業的股價和技術指標</a>！</p>



<h3 id="程式檔案連結">程式檔案連結</h3>



<p><a href="https://github.com/benbilly3/bokeh_explore" target="_blank" rel="noopener">https://github.com/benbilly3/bokeh_explore</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.finlab.tw/python-bokeh1-setup-and-first-impression/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1120</post-id>	</item>
		<item>
		<title>Bokeh 探索頻道(2)~客製化技術圖表升級</title>
		<link>https://www.finlab.tw/bokeh-stock-chart-with-technical-analysis/</link>
					<comments>https://www.finlab.tw/bokeh-stock-chart-with-technical-analysis/#respond</comments>
		
		<dc:creator><![CDATA[Ben]]></dc:creator>
		<pubDate>Mon, 20 Jul 2020 12:02:48 +0000</pubDate>
				<category><![CDATA[財經PYTHON教學]]></category>
		<category><![CDATA[BOKEH]]></category>
		<category><![CDATA[PYTHON]]></category>
		<category><![CDATA[資料視覺化]]></category>
		<guid isPermaLink="false">http://34.96.136.135/?p=1163</guid>

					<description><![CDATA[改造動機
上次介紹了Bokeh厲害的地方，那可不可以應用到投資圖表的繪製呢？
在Hahow課程：『Python 理財：打造小資族選股策略』的單元20中，韓老師用Talib和matplotlib套件示範了如何提取資料和客製化技術圖表繪圖，點出應用方向，然而課程重點是放在選股，不是在視覺化，圖表功能比較簡單，當時Bokeh也沒那麼厲害。]]></description>
										<content:encoded><![CDATA[
<h3 id="改造動機">改造動機</h3>



<p><a href="https://www.finlab.tw/python-bokeh1-setup-and-first-impression/">上次介紹了Bokeh厲害的地方</a>，那可不可以應用到投資圖表的繪製呢？<br>在Hahow課程：『Python 理財：打造小資族選股策略』的單元20中，韓老師用Talib和matplotlib套件示範了如何提取資料和客製化技術圖表繪圖，點出應用方向，然而課程重點是放在選股，不是在視覺化，圖表功能比較簡單，當時Bokeh也沒那麼厲害。</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="1024" height="557" src="http://34.96.136.135/wp-content/uploads/2020/07/Q8hEt30-1-1024x557.png" alt="Q8hEt30 1" class="wp-image-1165" srcset="https://www.finlab.tw/wp-content/uploads/2020/07/Q8hEt30-1-1024x557.png 1024w, https://www.finlab.tw/wp-content/uploads/2020/07/Q8hEt30-1-300x163.png 300w, https://www.finlab.tw/wp-content/uploads/2020/07/Q8hEt30-1-768x418.png 768w, https://www.finlab.tw/wp-content/uploads/2020/07/Q8hEt30-1-1536x836.png 1536w, https://www.finlab.tw/wp-content/uploads/2020/07/Q8hEt30-1.png 2035w" sizes="(max-width: 1024px) 100vw, 1024px" title="Bokeh 探索頻道(2)~客製化技術圖表升級 8"></figure></div>



<p>有些同學希望能有更精美的圖表可使用，搭配課程精彩的選股程式技巧，不就更完美了？這個願望今天就可以實現，後面有銜接課程的程式碼直接提供使用。<br>現在有Bokeh的幫忙，用Python也能打造不錯的互動圖表效果，接下來就要綜合小資族課程、Bokeh、網路上各路技巧，來打造適用於Hahow課程的新圖表。沒參與課程的可以用github 連結裡的demo_json檔來試試，只要資料格式對應，都可使用。</p>



<h4 id="github-https-github-com-benbilly3-bokeh-explore">github:<a href="https://github.com/benbilly3/bokeh_explore" rel="noreferrer noopener" target="_blank">https://github.com/benbilly3/bokeh_explore</a></h4>



<p>使用的程式檔為technical_chart。</p>



<h3 id="繪圖技巧說明">繪圖技巧說明</h3>



<p>寫Python就要利用其他魔法師的咒語，省時有效率，先來Bokeh gallery看看沒有範例。<br>結果有現成的Ｋ線圖範例，太好了！</p>



<figure class="wp-block-image"><img src="https://i.imgur.com/wjTomBS.png" alt="wjTomBS" title="Bokeh 探索頻道(2)~客製化技術圖表升級 9"></figure>



<p>雖然仍是陽春的靜態圖，但至少有了改造藍圖，從官網的程式碼：<br><a href="https://docs.bokeh.org/en/latest/docs/gallery/candlestick.html" rel="noreferrer noopener" target="_blank">https://docs.bokeh.org/en/latest/docs/gallery/candlestick.html</a></p>



<p>可以發現bokeh輕鬆地用pandas分類紅黑棒資料，再用segment畫引線和用vbar畫長棒圖。眼尖的人可以發現股價碰到假日的時候會有空值，這造成閱讀上有些礙眼，能否有讓時間序列日期資料的解決辦法呢？</p>



<p>在還不熟bokeh的時候，stackoverflow也是我們好朋友．．．處理關鍵在讓日期轉為文字，不用會自動補假日日期的datetime。</p>



<pre class="wp-block-code"><code lang="python" class="language-python line-numbers">fig.xaxis.major_label_overrides = {
            i: date.strftime('%Y/%m/%d') for i, date in enumerate(pd.to_datetime(df["date"]))
            # pd.date_range(start='3/1/2000', end='1/08/2018')
        }</code></pre>



<p>bokeh是物件導向繪圖庫，都封裝相當好，基本上沒啥程式技巧，就像玩樂高積木一樣，搜尋工具來堆，不難，比較繁瑣，內容頗多。<br>接著主要會實踐下列功能到圖表，有興趣學的可以看連結。</p>



<h4 id="1-figure圖紙設定，bokeh各種models應用">1. figure圖紙設定，bokeh各種models應用</h4>



<p><a href="https://docs.bokeh.org/en/latest/docs/reference/plotting.html" target="_blank" rel="noopener">https://docs.bokeh.org/en/latest/docs/reference/plotting.html</a></p>



<h4 id="2-處理假日日期造成的資料不連續問題，x-range-overwrite技巧">2. 處理假日日期造成的資料不連續問題，x_range overwrite技巧</h4>



<p><a href="https://stackoverflow.com/questions/23585545/how-do-i-make-bokeh-omit-missing-dates-when-using-datetime-as-x-axis" target="_blank" rel="noopener">https://stackoverflow.com/questions/23585545/how-do-i-make-bokeh-omit-missing-dates-when-using-datetime-as-x-axis</a></p>



<h4 id="3-hover互動資料顯示">3. hover互動資料顯示</h4>



<p><a href="https://docs.bokeh.org/en/latest/docs/user_guide/tools.html" target="_blank" rel="noopener">https://docs.bokeh.org/en/latest/docs/user_guide/tools.html</a></p>



<h4 id="4-legend物件控制，從label控制線圖開關。將legend移到圖表外，讓版面清晰。">4. legend物件控制，從label控制線圖開關。將legend移到圖表外，讓版面清晰。</h4>



<p><a href="https://stackoverflow.com/questions/26254619/position-of-the-legend-in-a-bokeh-plothttps://docs.bokeh.org/en/latest/docs/user_guide/interaction/legends.html" target="_blank" rel="noopener">https://stackoverflow.com/questions/26254619/position-of-the-legend-in-a-bokeh-plothttps://docs.bokeh.org/en/latest/docs/user_guide/interaction/legends.html</a></p>



<h4 id="5-位移、縮放、十字線、重置、存檔工具">5. 位移、縮放、十字線、重置、存檔工具</h4>



<p><a href="https://docs.bokeh.org/en/latest/docs/user_guide/tools.html" target="_blank" rel="noopener">https://docs.bokeh.org/en/latest/docs/user_guide/tools.html</a></p>



<h4 id="6-second-y-ranges繪製-使用雙軸">6. second y_ranges繪製(使用雙軸)</h4>



<p><a href="https://docs.bokeh.org/en/latest/docs/user_guide/plotting.html#userguide-plotting-twin-axes" target="_blank" rel="noopener">https://docs.bokeh.org/en/latest/docs/user_guide/plotting.html#userguide-plotting-twin-axes</a></p>



<h4 id="7-利用vbar和segment快速繪製k線-並將均線帶入。">7. 利用vbar和segment快速繪製k線,並將均線帶入。</h4>



<p><a href="https://docs.bokeh.org/en/latest/docs/gallery/candlestick.html" target="_blank" rel="noopener">https://docs.bokeh.org/en/latest/docs/gallery/candlestick.html</a></p>



<h4 id="8-建立技術線子圖組">8. 建立技術線子圖組</h4>



<p><a href="https://docs.bokeh.org/en/latest/docs/user_guide/layout.html#userguide-layout" target="_blank" rel="noopener">https://docs.bokeh.org/en/latest/docs/user_guide/layout.html#userguide-layout</a></p>



<h5 id="經過神奇的魔法就有hahow課程的進化版，包含以上的功能，實踐了不錯的效果！加入output-file-‘檔名’-就可產生html檔在瀏覽器使用，只要再寫一個傳導查詢變數的API，就能串接做一個服務出來，之後會講用FastApi寫後端來串Bokeh。">經過神奇的魔法就有hahow課程的進化版，包含以上的功能，實踐了不錯的效果！加入output_file(‘檔名’)就可產生html檔在瀏覽器使用，只要再寫一個傳導查詢變數的API，就能串接做一個服務出來，之後會講用FastApi寫後端來串Bokeh。</h5>



<figure class="wp-block-image"><img src="https://i.imgur.com/4BY8lBt.png" alt="4BY8lBt" title="Bokeh 探索頻道(2)~客製化技術圖表升級 10"></figure>



<h3 id="課程相容資料提取工具">課程相容資料提取工具</h3>



<h4 id="從python小資族的sqlite提取資料">從python小資族的sqlite提取資料</h4>



<p>若DB為pickle檔，須將pd.read_sql那行修改為read_pickle，並要注意格式。</p>



<p>如果有上過韓老師python小資族，可將course11.ipynb上頭用read_sql取資料的程式改為下部份取資料，輸入股號和資料開始日期，產出的data丟入後面的繪圖程式，即可產生互動式圖表。</p>



<pre class="wp-block-code"><code lang="python" class="language-python line-numbers">import pandas as pd
import sqlite3
import os
import json
from talib import abstract


def get_price_data(stock_id,date):
    # connect to sql
    conn = sqlite3.connect(os.path.join('data', "data.db"))
    # read data from sql
    df = pd.read_sql(f"select stock_id,證券名稱, date, 開盤價, 收盤價, 最高價, 最低價, 成交股數 from price where stock_id='{stock_id}' and date > '{date}'", conn,
        index_col=['date'])
    # rename the columns of dataframe
    df.index=df.index.astype(str).str.split(" ").str[0]
    df.rename(columns={'收盤價':'close','證券名稱':'name', '開盤價':'open', '最高價':'high', '最低價':'low', '成交股數':'volume'}, inplace=True)
    df['MA5']=df['close'].rolling(5).mean()
    df['MA10']=df['close'].rolling(10).mean()
    df['MA20']=df['close'].rolling(20).mean()
    df['MA60']=df['close'].rolling(60).mean()
    df['MA120']=df['close'].rolling(120).mean()
    df['volume']=df['volume']/1000

    
    RSI = pd.DataFrame(abstract.RSI(df, timeperiod=12),columns=['RSI_12'])
    RSI['RSI_36']=abstract.RSI(df, timeperiod=36)
    RSI=RSI.to_dict()
    STOCH = abstract.STOCH(df).to_dict()
    MACD=abstract.MACD(df).to_dict()
    basic=df.iloc[-1,:2].to_dict()
    df=df.drop(columns=['stock_id','name']).to_dict()
    data={'basic':basic,'price_df':df,'RSI':RSI,'STOCH' :STOCH,'MACD':MACD }
    
    return data</code></pre>



<h3 id="程式碼下載">程式碼下載</h3>



<p>使用的繪圖程式檔為technical_chart，將get_price_data(stock_id,date)帶入technical_chart(json_df)即可繪圖，可到gitlab下載bokeh_explore。</p>



<h4 id="github-https-github-com-benbilly3-bokeh-explore-1">github:<a href="https://github.com/benbilly3/bokeh_explore" rel="noreferrer noopener" target="_blank">https://github.com/benbilly3/bokeh_explore</a></h4>



<pre class="wp-block-code"><code lang="python" class="language-python line-numbers">import pandas as pd
from bokeh.io import show, output_file, output_notebook
from bokeh.plotting import figure
from bokeh.models import SingleIntervalTicker, LinearAxis, ColumnDataSource, HoverTool
from bokeh.palettes import Spectral4, Dark2
from bokeh.models import LinearAxis, Range1d, Legend
from bokeh.layouts import column


def technical_chart(json_df):
    # get data
    stock_data = json_df
    df = pd.DataFrame(stock_data['price_df']).reset_index().rename(columns={'index': 'date'})
    df = df.reset_index()
    inc = df.close > df.open
    dec = df.open > df.close
    inc_data = df[inc]
    dec_data = df[dec]
    df_source = ColumnDataSource(df)
    inc_source = ColumnDataSource(inc_data)
    dec_source = ColumnDataSource(dec_data)

    # set hover
    hover = HoverTool(
        tooltips=[
            ("date", "@date"),
            ("close", "@open"),
            ("open", "@close"),
            ("high", "@high"),
            ("low", "@low"),
            ("volume", "@volume")
        ],
        formatters={"@date": "datetime"}
    )

    hover_rsi_kd = HoverTool(
        tooltips=[
            ("date", "@date"),
            ("RSI_12", "@RSI_12"),
            ("RSI_36", "@RSI_36"),
            ("slowk", "@slowk"),
            ("slowd", "@slowd"),

        ],
        formatters={"@date": "datetime"}

    )

    hover_macd = HoverTool(
        tooltips=[
            ("date", "@date"),
            ("macd", "@macd"),
            ("macdsignal", "@macdsignal"),
            ("macdhist", "@macdhist"),
        ],
        formatters={"@date": "datetime"}

    )

    # set figure data
    basic_data = stock_data['basic']
    title = basic_data['stock_id'] + ' ' + basic_data['name'] + ' ' + 'technical_chart'
    x_end = len(df)
    show_init_num = 120
    x_start = x_end - show_init_num
    interval_freq = show_init_num / 12
    y_start = df['close'].min() * 0.95
    y_end = df['close'].max() * 1.05
    p1 = figure(plot_width=1000, title=title, plot_height=500, x_range=(x_start, x_end), y_range=(y_start, y_end),
                tools=[hover, "pan,zoom_in,zoom_out,crosshair,reset,save"], toolbar_location="above" ,y_axis_label="price")
    p2 = figure(plot_width=1000, title='RSI&amp;KD', plot_height=250, x_range=(x_start, x_end),
                background_fill_color="#fafafa", tools=[hover_rsi_kd, "pan,zoom_in,zoom_out,crosshair,reset,save"],
                toolbar_location="above")
    p3 = figure(plot_width=1000, title='MACD', plot_height=250, x_range=(x_start, x_end),
                background_fill_color="#fafafa", tools=[hover_macd, "pan,zoom_in,zoom_out,crosshair,reset,save"],
                toolbar_location="above")

    for fig in [p1, p2, p3]:
        fig.title.text_font_size = '16pt'

        # map dataframe indices to date strings and use as label overrides
        fig.xaxis.major_label_overrides = {
            i: date.strftime('%Y/%m/%d') for i, date in enumerate(pd.to_datetime(df["date"]))
            # pd.date_range(start='3/1/2000', end='1/08/2018')
        }
        fig.xaxis.ticker = SingleIntervalTicker(interval=interval_freq)

    # set k bar chart
    # use the *indices* for x-axis coordinates, overrides will print better labels
    p1.segment('index', 'high', 'index', 'low', color="black", source=df_source)
    p1.vbar('index', 0.5, 'open', 'close', fill_color="#eb2409", line_color="black", source=inc_source)
    p1.vbar('index', 0.5, 'open', 'close', fill_color="#00995c", line_color="black", source=dec_source)

    # set ma line
    ma_legend_items = []
    for ma_name, color in zip(["MA5", "MA10", "MA20", "MA60", "MA120"], Dark2[5]):
        ma_df = df[['index', 'date', 'close', 'open', 'high', 'low', 'volume', ma_name]]
        source = ColumnDataSource(ma_df)
        ma_line = p1.line(x="index", y=ma_name, line_width=2, color=color, alpha=0.8,
                          muted_color=color, muted_alpha=0.2, source=source)
        ma_legend_items.append((ma_name, [ma_line]))

    # set ma legend
    legend = Legend(items=ma_legend_items, location=(0, 250))
    p1.add_layout(legend, 'left')

    # set twinx for volume
    y2_start = df['volume'].min() * 0.95
    y2_end = df['volume'].max() * 2
    p1.extra_y_ranges = {"vol": Range1d(y2_start, y2_end)}
    p1.vbar('index', 0.5, 'volume', y_range_name='vol', color='blue', alpha=0.2, source=df_source)
    p1.add_layout(LinearAxis(y_range_name="vol" ,axis_label="vol"), 'right')

    # RSI Chart
    rsi_df = pd.DataFrame(stock_data['RSI']).reset_index().rename(columns={'index': 'date'})
    kd_df = pd.DataFrame(stock_data['STOCH']).reset_index().rename(columns={'index': 'date'})
    rsi_kd_df = pd.concat([rsi_df, kd_df], axis=1)
    rsi_source = ColumnDataSource(rsi_kd_df)

    rsi_kd_legend_items = []
    for index_name, color in zip(["RSI_12", "RSI_36", "slowk", "slowd"], Spectral4):
        index_line = p2.line('index', index_name, line_width=3, color=color, alpha=0.8, muted_color=color,
                             muted_alpha=0.2, source=rsi_source)

        rsi_kd_legend_items.append((index_name, [index_line]))

    # set rsi_kd legend
    legend = Legend(items=rsi_kd_legend_items, location=(0, 50))
    p2.add_layout(legend, 'left')

    # MACD Chart
    macd = pd.DataFrame(stock_data['MACD']).reset_index().rename(columns={'index': 'date'})
    macd = macd.reset_index()
    macd_source = ColumnDataSource(macd)

    macd_legend_items = []
    for index_name, color in zip(["macd", "macdsignal", "macdhist"], Dark2[3]):
        if index_name == "macdhist":
            index_line = p3.vbar('index', 0.5, index_name, color=color, alpha=0.8, muted_color=color, muted_alpha=0.2,
                                 source=macd_source)
        else:
            index_line = p3.line('index', index_name, line_width=3, color=color, alpha=0.8, muted_color=color,
                                 muted_alpha=0.2, source=macd_source)

        macd_legend_items.append((index_name, [index_line]))

    # set macd legend
    legend = Legend(items=macd_legend_items, location=(0, 50))
    p3.add_layout(legend, 'left')

    # set legend mode
    for fig in [p1, p2, p3]:
        # set legend
        fig.legend.label_text_font_size = '8pt'
        # use hide or mute
        fig.legend.click_policy = "hide"
        #     fig.add_layout(legend, 'left')
    
    # use brower output
#     output_file("candlestick.html", title="candlestick.py example")
    # use jupyter output
    output_notebook()
    # use columns to control all fig  locations,you could try row method.
    show(column(p1, p2, p3))</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://www.finlab.tw/bokeh-stock-chart-with-technical-analysis/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1163</post-id>	</item>
		<item>
		<title>用 Python 打造投資網站(1) &#8211; 開啟地圖</title>
		<link>https://www.finlab.tw/financial-website-building-part1/</link>
					<comments>https://www.finlab.tw/financial-website-building-part1/#respond</comments>
		
		<dc:creator><![CDATA[Ben]]></dc:creator>
		<pubDate>Mon, 20 Jul 2020 06:15:28 +0000</pubDate>
				<category><![CDATA[財經PYTHON教學]]></category>
		<category><![CDATA[BOKEH]]></category>
		<category><![CDATA[PYTHON]]></category>
		<category><![CDATA[資料視覺化]]></category>
		<guid isPermaLink="false">http://34.96.136.135/?p=1167</guid>

					<description><![CDATA[策略、圖表、資料、串接服務越來越多，你是不是有發現用Jupyter難以管理眾多的程式檔案、資料庫？當我出門在外，身上沒電腦，如何用手機監控投資策略、查詢資料？如何做自動化交易？電腦規格不夠、跑機器學習、讀資料好慢，可不可以用雲端運算服務？想讓朋友家人也能使用我的策略？市面上看盤和選股網站介面不合個人需求，想自己打造！]]></description>
										<content:encoded><![CDATA[
<h2 id="動機：">動機：</h2>



<ol><li>策略、圖表、資料、串接服務越來越多，你是不是有發現用Jupyter難以管理眾多的程式檔案、資料庫？</li><li>當我出門在外，身上沒電腦，如何用手機監控投資策略、查詢資料？</li><li>如何做自動化交易？</li><li>電腦規格不夠、跑機器學習、讀資料好慢，可不可以用雲端運算服務？</li><li>想讓朋友家人也能使用我的策略？</li><li>市面上看盤和選股網站介面不合個人需求，想自己打造<br>…..</li></ol>



<p>當你熟悉Finlab課程後，你會發現知識爆炸、神招好多，若有一個魔杖可把這些Python魔法整合起來，管理和發招上一定更方便，程式碼也較容易維護。<br>這時用打造客製化的投資網站可以解決我們的問題。</p>



<h2 id="Python能打造網站嗎？">Python能打造網站嗎？</h2>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="676" height="126" src="http://34.96.136.135/wp-content/uploads/2020/07/Ioom2TE.png" alt="Ioom2TE" class="wp-image-1168" srcset="https://www.finlab.tw/wp-content/uploads/2020/07/Ioom2TE.png 676w, https://www.finlab.tw/wp-content/uploads/2020/07/Ioom2TE-300x56.png 300w" sizes="(max-width: 676px) 100vw, 676px" title="用 Python 打造投資網站(1) - 開啟地圖 11"></figure></div>



<p>以守備範圍超廣的Python，當然可以打造網站，<strong>用Python建站有個其他語言的好處是可以把Python的強項，如爬蟲、統計、數據分析、機器學習也包進來。</strong></p>



<p>只是大部分的新創企業拿Python來做後端服務居多，前端圖表雖然已有pyecharts、bokeh等函數庫可支援，但靈活性上還是有不足Java Script的部分。</p>



<p>後端框架有重量包Django可選擇、輕量武器有Flask以及新竄起的Fastapi。</p>



<h2 id="Python寫網站難嗎？">Python寫網站難嗎？</h2>



<p>Python是最容易上手的語言，而寫網站是把Python語言觀念集成的場域，物件導向要有一定掌握，你才能寫出易維護、流暢的程式碼。一開始會有點難度，但你若想精通Python，這是必經之路。<br>若能藉由學習打造網站的技能，讓投資效率、程式能力都能一同成長，一舉數得，不是很棒的事嗎？</p>



<h2 id="如何開始大冒險？">如何開始大冒險？</h2>



<p>沒有工程圖，不知整體架構，連前進的方向都沒有。<br>這點我幫你解決了。<br>以下是我寫的網站架構圖與技能樹，應能整合課程內容與眾服務，用Python打造投資生態系，有以下特點。</p>



<ol><li>以Django為核心，MVC架構，控制商業模型、資料庫，自帶會員系統，方便將來擴展。</li><li>使用Fastapi撰寫Restful API，簡單高效，自帶Swagger API測試文檔。</li><li>串連finlab hahow課程裡的Jupyter策略，共用網站資料庫。</li><li>使用Django-Q的多進程服務做爬蟲排程管理，結合Django自帶的Admin UI，方便設定，串接Line Notify，得知爬蟲與策略執行狀況。</li><li>AWS雲端部署與資料庫服務。</li><li>串接永豐金等券商的API做交易機器人。</li><li>可採前後端分離，前端改以React取代Django的弱點Template(看個人偏好而定)。</li></ol>



<figure class="wp-block-image"><a href="https://i.imgur.com/BY2MW6Q.jpg" target="_blank" rel="noopener"><img src="https://i.imgur.com/BY2MW6Q.jpg" alt="BY2MW6Q" title="用 Python 打造投資網站(1) - 開啟地圖 12"></a></figure>



<p>乍看開始有點複雜，要學的有點多，但若有熱情與動機整合投資與程式的結合，這絕對是令人興奮的開始，Python實在太萬能了！<br></p>



<p>萬事起頭難，之後會一步步來和大家分享探索的心得。</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.finlab.tw/financial-website-building-part1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1167</post-id>	</item>
	</channel>
</rss>
