基于Plotly go.Scatter实现带动态颜色的多子图折线图
实现Plotly子图及根据收盘价动态变色的折线图
解决方案代码
import plotly.graph_objects as go from plotly.subplots import make_subplots import yfinance as yf # 下载数据并预处理 df = yf.download("AAPL MSFT", start="2022-01-01", end="2022-07-01", group_by='ticker') df.reset_index(inplace=True) # 拆分单个股票的数据,简化后续处理 aapl_df = df.xs('AAPL', axis=1, level=0).copy() aapl_df['Date'] = df['Date'] msft_df = df.xs('MSFT', axis=1, level=0).copy() msft_df['Date'] = df['Date'] # 新增颜色编码列:以收盘价均值为阈值,高于均值用深绿,低于用深红(两种颜色示例) # 可替换为固定阈值,比如 lambda x: 'green' if x > 150 else 'red' aapl_threshold = aapl_df['Close'].mean() aapl_df['Color'] = aapl_df['Close'].apply(lambda x: 'darkgreen' if x > aapl_threshold else 'crimson') msft_threshold = msft_df['Close'].mean() msft_df['Color'] = msft_df['Close'].apply(lambda x: 'darkgreen' if x > msft_threshold else 'crimson') # 创建2行1列的子图,共享X轴 fig = make_subplots( rows=2, cols=1, vertical_spacing=0.1, shared_xaxes=True, subplot_titles=('AAPL 收盘价走势', 'MSFT 收盘价走势') ) # 添加AAPL的折线图到第1行子图 fig.add_trace( go.Scatter( x=aapl_df['Date'], y=aapl_df['Close'], marker_color=aapl_df['Color'], mode='lines+markers', name="AAPL", line=dict(color='gray', width=1) # 灰色折线打底,标记点颜色随收盘价变化 ), row=1, col=1 ) # 添加MSFT的折线图到第2行子图 fig.add_trace( go.Scatter( x=msft_df['Date'], y=msft_df['Close'], marker_color=msft_df['Color'], mode='lines+markers', name="MSFT", line=dict(color='gray', width=1) ), row=2, col=1 ) # 布局优化 fig.update_layout( height=600, width=800, title_text='个股收盘价动态颜色走势', showlegend=True ) # 设置Y轴标签 fig.update_yaxes(title_text="收盘价(USD)", row=1, col=1) fig.update_yaxes(title_text="收盘价(USD)", row=2, col=1) fig.show()
关键说明
- 数据拆分:利用
xs方法拆分yfinance返回的多层列数据,将每个股票的行情数据单独提取,简化后续颜色列的生成逻辑。 - 动态颜色实现:通过
apply方法为每个收盘价分配颜色,示例采用均值作为阈值区分两种颜色,你可以根据需求替换为固定数值(比如x > 150)或其他统计量(如中位数)。 - 子图配置:通过
make_subplots创建多行子图,开启shared_xaxes=True实现X轴共享,减少重复视觉元素;vertical_spacing控制子图间的垂直间距。 - 折线与点颜色说明:Plotly的
go.Scatter无法直接为折线的每个线段设置不同颜色,因此示例中用灰色折线打底,重点通过标记点的颜色体现收盘价的高低差异。如果需要折线完全随价格变色,可通过循环生成相邻点的短线段实现,示例如下:
# 折线随价格变色的补充实现(以AAPL为例) for i in range(len(aapl_df)-1): fig.add_trace( go.Scatter( x=[aapl_df['Date'].iloc[i], aapl_df['Date'].iloc[i+1]], y=[aapl_df['Close'].iloc[i], aapl_df['Close'].iloc[i+1]], line=dict(color=aapl_df['Color'].iloc[i], width=2), showlegend=False ), row=1, col=1 )
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

