Chuyển đến nội dung chính

Hướng dẫn Triển khai Ứng dụng Web với Bokeh

Học cách tạo và triển khai một ứng dụng web so sánh giá cổ phiếu bằng Bokeh. Vận dụng kỹ năng trực quan hóa với Python Bokeh để tạo một công cụ thực tiễn, tương tác.
Đã cập nhật 5 thg 10, 2026  · 9 phút đọc

Khám phá cùng AI

ChatGPTClaudePerplexity

Người dùng vừa dùng laptop vừa dùng điện thoại, làm việc với mã nguồn.

Trong các hướng dẫn Bokeh trước đây, chúng tôi đã đề cập cách bắt đầu với Bokeh và tạo một số biểu đồ tán xạ và đường cơ bản. Bên cạnh khả năng trực quan hóa dữ liệu phong phú, Bokeh còn cho phép người dùng lưu trữ ứng dụng trên máy chủ của họ bằng cách thiết lập kết nối giữa Python và trình duyệt.   

Chúng ta sẽ bắt đầu bằng cách tạo ứng dụng và chạy nó trên máy chủ Bokeh để chia sẻ với đồng nghiệp. Để biết thêm thông tin về cách hoạt động của máy chủ Bokeh, hãy xem tài liệu Bokeh. 

Các khái niệm cơ bản về Bokeh Server

Bokeh chuyển đổi các đối tượng (như biểu đồ, widget, trục và hầu như mọi thứ bạn tạo) sang định dạng JSON.

Máy chủ Bokeh chuyển đổi mã Python bạn viết thành một tài liệu JSON. Tài liệu JSON này được hiển thị bằng JavaScript thông qua thư viện phía khách của Bokeh (BokehJS) để người dùng xem ứng dụng trong trình duyệt.

Ưu điểm của Bokeh là nó xử lý phần JavaScript. Do đó, bạn không cần kiến thức JavaScript trước đó để tạo ứng dụng! Hình minh họa sau tóm tắt cách máy chủ Bokeh hoạt động.

Bokeh Server

Nguồn: The Bokeh Server

Cách xây dựng và chạy một ứng dụng Bokeh

Cấu trúc chung của một ứng dụng Bokeh là:

  1. Tạo biểu đồ và widget: Đây là bước đầu tiên để tạo một ứng dụng Bokeh. Bạn nên có sẵn một biểu đồ muốn trình bày.
  2. Định nghĩa hàm callback: Hàm callback hướng dẫn ứng dụng phản hồi thế nào trước tương tác của người dùng. Ví dụ, khi bạn chọn mã cổ phiếu khác trong biểu đồ chuỗi thời gian, biểu đồ sẽ cập nhật với dữ liệu mới.
  3. Tạo bố cục (layout): Bố cục giúp trình bày biểu đồ hiệu quả và đẹp mắt.

Tạo ứng dụng web phân tích thị trường chứng khoán với Bokeh

Mô tả dự án

Trong phần này, chúng tôi sẽ hướng dẫn bạn cách tạo một ứng dụng web đơn giản và triển khai để các nhà phân tích tài chính sử dụng.

Hãy tưởng tượng bạn đang làm việc cho Big Money Inc — một công ty quản lý tài sản hàng đầu. Quản lý của bạn đã nghe đồng nghiệp khen ngợi kỹ năng Python của bạn. Giờ đây, cô ấy muốn bạn tạo một ứng dụng chứng khoán để các nhà phân tích tài chính của công ty dùng so sánh hai mã cổ phiếu. Cô ấy tin rằng các nhà phân tích có thể tiết kiệm thời gian bằng cách nhanh chóng so sánh bất kỳ cổ phiếu nào với một cổ phiếu tương tự trong cùng ngành. Ví dụ, họ có thể so sánh cổ phiếu của Apple với Microsoft và chọn cổ phiếu tốt nhất để xây dựng danh mục cho khách hàng. Việc so sánh nên bao gồm các thước đo cơ bản như:

  • Biểu đồ xu hướng giá đóng cửa
  • Tương quan
  • Trung bình (lợi nhuận kỳ vọng)
  • Độ lệch chuẩn (rủi ro kỳ vọng)

Cần có cách tùy chỉnh khoảng thời gian phân tích một cách tương tác. Ví dụ, người dùng có thể so sánh hiệu suất của hai cổ phiếu trong tuần, tháng, năm gần đây, hoặc bất kỳ giai đoạn nào họ muốn. Bạn cần đảm bảo ứng dụng luôn sẵn sàng cho tất cả người dùng trong công ty. Điều này có nghĩa là bạn cần triển khai nó bằng một dịch vụ đám mây.

Yêu cầu tiên quyết

  1. Hiểu biết cơ bản về Bokeh.
  2. Một chút kiến thức về Python.
  3. Đã cài đặt các gói được nêu trong Hướng dẫn Bắt đầu với Bokeh.

Tổng quan về ứng dụng web thị trường chứng khoán

Ứng dụng web sẽ cung cấp lời giải cho bài toán tài chính nêu trên. Ứng dụng cho phép người dùng chọn hai mã cổ phiếu và trực quan hóa thống kê mô tả (như trung bình và độ lệch chuẩn) của cả giá và lợi nhuận, biểu đồ tương quan, và biểu đồ xu hướng giá cho các cổ phiếu được chọn. Tính tương tác được tạo bằng cách cho phép chọn kết hợp các mã cổ phiếu khác nhau và các khoảng thời gian khác nhau (trên biểu đồ xu hướng giá). Ứng dụng web sẽ trông như sau:

Giao diện Ứng dụng Web so sánh cổ phiếu với Bokeh

Tạo dự án Bokeh cho ứng dụng web thị trường chứng khoán

1. Bạn cần tạo một thư mục dự án và đặt tên là SelectStock.

2. Mở thư mục dự án và tạo tệp tên main.py.

3. Lưu một bản dữ liệu thị trường chứng khoán vào thư mục dự án với tên “all_stocks_5yr.csv”. 

Lưu một bản danh sách mã cổ phiếu. Tệp ticker.py chứa danh sách các mã. Chỉ có 505 mã cổ phiếu, vì đưa toàn bộ danh sách vào mã trong main.py có thể làm rườm rà. Hợp lý hơn là lưu danh sách mã cổ phiếu trong tệp riêng và gọi khi cần.

Mở tệp main.py trong trình soạn thảo yêu thích như Spyder, atom hoặc Sublime Text.

Import gói

Gõ đoạn mã sau vào tệp main.py. Đoạn mã này import các gói và danh sách mã cần thiết để tạo ứng dụng web:

# Import the required packages
import pandas as pd
from functools import lru_cache
from bokeh.io import curdoc
from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, PreText, Select, Div
from bokeh.plotting import figure

# load the list of tickers
import tickers
tickers = tickers.tickers

Đọc và nạp dữ liệu 

Viết một hàm để tránh so sánh một mã với chính nó:

# Create a function to ensure that a ticker is not compared to itself
def foo(val, lst):
return [x for x in lst if x != val]
Add the following code to read and load data for the webapp:
# A function to read and load data
# Note the use of @lru_cache() decorator is to cache the data and speed up reloads
@lru_cache()
def load_ticker(ticker):
data = pd.read_csv('all_stocks_5yr.csv', parse_dates=['date'])
data = data.set_index('date')
data = data[data['Name'] == ticker]
return pd.DataFrame({ticker: data.close, ticker+'_returns': data.close.diff()})

# A function to create a dataframe for the selected tickers
@lru_cache()
def get_data(t1, t2):
df1 = load_ticker(t1)
df2 = load_ticker(t2)
data = pd.concat([df1, df2], axis=1)
data = data.dropna()
data['t1'] = data[t1]
data['t2'] = data[t2]
data['t1_returns'] = data[t1+'_returns']
data['t2_returns'] = data[t2+'_returns']
return data

# Put data into a ColumnDataSource
source = ColumnDataSource(
data=dict(date=[], t1=[], t2=[], t1_returns=[], t2_returns=[]))

Tạo widget

# set up widgets
stats = PreText(text='', width=500)
ticker1 = Select(value='AAPL', options=foo('GOOG', tickers))
ticker2 = Select(value='GOOG', options=foo('AAPL', tickers))

Các widget cho phép người dùng chọn mã thứ nhất và mã thứ hai để so sánh. Sau khi bạn chọn mã, Bokeh có thể tạo biểu đồ.

Tạo biểu đồ

# set up plots
tools = 'pan,wheel_zoom,xbox_select,reset'

corr = figure(width=400, height=350,
              tools='pan,wheel_zoom,box_select,reset', output_backend='webgl')
corr.diamond('t1_returns', 't2_returns', size=2, source=source, color="red",
            selection_color="orange", alpha=0.6, nonselection_alpha=0.1, selection_alpha=0.4)


time_series1 = figure(width=900, height=200, tools=tools,
                      x_axis_type='datetime', active_drag="xbox_select", output_backend='webgl')
time_series1.line('date', 't1', source=source, color='orange')
time_series2 = figure(width=900, height=200, tools=tools,
                      x_axis_type='datetime', active_drag="xbox_select", output_backend='webgl')
time_series2.x_range = time_series1.x_range
time_series2.line('date', 't2', source=source, color='green')

Trong đoạn mã này, trước tiên chúng ta xác định các công cụ đi kèm biểu đồ. Biểu đồ tương quan là biểu đồ đầu tiên, với hàm figure() đặt width = 400 và height = 350. Biểu đồ tương quan dùng dấu kim cương làm marker.

Chúng ta dùng glyph line để tạo các biểu đồ chuỗi thời gian cho các mã. Phạm vi trục thời gian được đồng bộ để so sánh chính xác.

# Define callbacks
def change_ticker1(attrname, old, new):
ticker2.options = foo(new, tickers)
update()

def change_ticker2(attrname, old, new):
ticker1.options = foo(new, tickers)
update()

def update(selected=None):
t1, t2 = ticker1.value, ticker2.value

df = get_data(t1, t2)
data = df[['t1', 't2', 't1_returns', 't2_returns']]
source.data = data

update_stats(df, t1, t2)

corr.title.text = '%s returns vs. %s returns' % (t1, t2)
    time_series1.title.text, time_series2.title.text = t1, t2

def update_stats(data, t1, t2):
stats.text = str(data[[t1, t2, t1+'_returns', t2+'_returns']].describe())

ticker1.on_change('value', change_ticker1)
ticker2.on_change('value', change_ticker2)

def selection_change(attrname, old, new):
t1, t2 = ticker1.value, ticker2.value
data = get_data(t1, t2)
selected = source.selected.indices
if selected:
    data = data.iloc[selected, :]
update_stats(data, t1, t2)

source.selected.on_change('indices', selection_change)

Trong phần callback, hai hàm đầu lần lượt định nghĩa callback cho mã 1 và mã 2.

Hàm update() cập nhật biểu đồ mỗi khi người dùng chọn tổ hợp mã khác; hàm update_stats() cập nhật thống kê khi người dùng chọn bộ mã mới; và hàm selection_change() cập nhật toàn bộ ứng dụng khi người dùng cập nhật lựa chọn trên biểu đồ.

Thiết lập bố cục

Bước đầu tiên là đặt tiêu đề cho ứng dụng để hướng dẫn người dùng cách tương tác với ứng dụng web. Hàm Div cho phép bạn cung cấp văn bản và định nghĩa chiều cao, chiều rộng, cùng các tùy chỉnh khác.

# set up layout
# Add a title message to the app
div = Div(
    text="""
        <p>Chọn hai cổ phiếu để so sánh các thống kê chính:</p>
        """,
width=900,
height=30,
)
# Create layouts
app_title = div
widgets = column(ticker1, ticker2, stats)
main_row = row(widgets, corr)
series = column(time_series1, time_series2)
layout = column(app_title, main_row, series)

Bố cục ứng dụng kết hợp cả hàm column và row.

Trước tiên, tiêu đề được đặt ở trên cùng. Hàng chính được xếp ngay bên dưới (chứa thống kê mô tả và biểu đồ tương quan). Hàng tiếp theo chứa biểu đồ chuỗi thời gian đầu tiên (cho mã 1), và hàng cuối cùng chứa biểu đồ chuỗi thời gian cho mã thứ hai.

Khởi tạo ứng dụng

Bước này khởi tạo ứng dụng web khi được gọi trên máy chủ. 

# initialize the app
update()
curdoc().add_root(layout)
curdoc().title = "Compare Stocks"

Triển khai ứng dụng web

Để kiểm thử ứng dụng web, bạn có thể triển khai bằng máy cục bộ. Để làm vậy, chỉ cần mở Anaconda Prompt hoặc terminal bạn chọn. Di chuyển vào thư mục chứa thư mục dự án 'SelectStock'. Bạn có thể làm điều này bằng cách gõ lệnh sau:

cd "System path to where the SelectStock folder is contained"

ví dụ cd "C:\Users\... \SelectStock"

Gõ lệnh sau để chạy ứng dụng web:

bokeh serve --show SelectStock

Hoặc, bạn có thể điều hướng vào thư mục SelectStock và chạy tệp main.py:

Bokeh serve --show main.py

Thao tác này sẽ mở ứng dụng web trong trình duyệt mặc định tại:

http://localhost:5006/SelectStock hoặc

http://localhost:5006/main

Bạn đang sử dụng Bokeh Server để chạy và triển khai ứng dụng web của mình.

Bạn cũng có thể triển khai ứng dụng web bằng các dịch vụ như Heroku.

Kết luận

Trong hướng dẫn này, bạn đã học những điều cơ bản để xây dựng và triển khai ứng dụng Bokeh của riêng bạn trên máy cục bộ. Hướng dẫn cho thấy cách ghép nối những gì bạn đã học để xây dựng một ứng dụng thực tiễn, thú vị và tương tác, tạo hứng khởi cho người dùng.

Cách nhanh nhất để nâng cao kỹ năng lập trình là xây dựng các dự án như thế này sau khi học một khái niệm hoặc công cụ. Cách tiếp cận thực hành sẽ giúp bạn hiểu vững một công cụ hay kỹ năng và có thể cho nhà tuyển dụng tiềm năng thấy bạn đã làm gì.

Nếu bạn muốn tìm hiểu thêm về Bokeh, bạn có thể đọc cuốn sách này. Hoặc tốt hơn, hãy thử khóa học Interactive Visualization with Bokeh của DataCamp. Khóa học cung cấp chi tiết về Bokeh và cách tạo các biểu đồ nâng cao hơn. Bạn có thể tiến xa hơn và học cách xây dựng ứng dụng web Bokeh của riêng mình bằng dữ liệu thời gian thực. 

Chủ đề
Python
Trực quan hóa Dữ liệu
Liên quan

blog

Claude Opus 4.6: Tính năng, Điểm chuẩn, Bài kiểm tra thực hành và hơn thế nữa

Mô hình mới nhất của Anthropic dẫn đầu ở mã hóa tác tử và lập luận phức tạp. Thêm vào đó, nó có cửa sổ ngữ cảnh 1M.
Matt Crabtree's photo

Matt Crabtree

10 phút

Xem ThêmXem Thêm