使用Plotly基于时间戳绘制热力图:X轴日期显示不全问题排查
问题描述
我有如下数据(第一列为索引,非omicron列):
X_reduced_df[Heatmetrics]= omicron delta copy_number_1_a_liter copy_number_1_b_liter copy_number_1_c_liter copy_number_2_a_liter copy_number_2_b_liter copy_number_2_c_liter 0 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 1 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 2 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 3 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 4 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ... ... ... ... ... ... ... ... ... 393 0.000 0.000 38000.000 22725.000 52250000.000 27750.000 31250.000 36500000.000 394 0.000 0.000 38000.000 41500.000 28000000.000 38500.000 26750.000 29250000.000 395 0.000 0.000 49000.000 80500.000 30250000.000 59000.000 81500.000 40500000.000 396 0.000 0.000 15400.000 11500.000 3600000.000 20775.000 11350.000 6675000.000 397 0.000 0.000 35000.000 33500.000 35500000.000 30000.000 28750.000 37250000.000
其中Heatmetrics定义为:
Heatmetrics=[ 'omicron', 'delta', 'copy_number_1_a_liter', 'copy_number_1_b_liter', 'copy_number_1_c_liter', 'copy_number_2_a_liter', 'copy_number_2_b_liter', 'copy_number_2_c_liter']
时间戳数据如下:
X_reduced_df['EXTRACTION_DATE_SAMPLE']= EXTRACTION_DATE_SAMPLE 2021-07-13 2021-07-13 2021-07-18 2021-07-18 2021-07-21 2021-07-21 2021-07-24 2021-07-24 2021-07-27 2021-07-27 ... 2022-11-17 2022-11-17 2022-11-17 2022-11-17 2022-11-20 2022-11-20 2022-11-20 2022-11-20 2022-11-20 2022-11-20 Name: EXTRACTION_DATE_SAMPLE, Length: 398, dtype: datetime64[ns]
我执行了以下代码生成热力图:
df = X_reduced_df[Heatmetrics].to_numpy() dates= X_reduced_df['EXTRACTION_DATE_SAMPLE'].to_numpy() fig = go.Figure(data=go.Heatmap( z=df, x= dates, y=Heatmetrics, colorscale='Viridis')) fig.update_layout( title='BWB Heatmap', xaxis_nticks=50 ) fig.show()
当前生成的热力图X轴未显示全部日期,我希望实现Plotly官方示例的日期显示效果,官方示例代码如下:
import plotly.graph_objects as go import datetime import numpy as np np.random.seed(1) programmers = ['Alex','Nicole','Sara','Etienne','Chelsea','Jody','Marianne'] base = datetime.datetime.today() dates = base - np.arange(180) * datetime.timedelta(days=1) z = np.random.poisson(size=(len(programmers), len(dates))) fig = go.Figure(data=go.Heatmap( z=z, x=dates, y=programmers, colorscale='Viridis')) fig.update_layout( title='GitHub commits per day', xaxis_nticks=40) fig.show()
请问我的代码存在什么问题?如何实现官方示例的显示效果?已导入必要的库:
import plotly.express as px from plotly.offline import plot, iplot import plotly.graph_objects as go
问题分析与解决方案
问题原因
- 日期格式识别失效:你将日期转为numpy数组(
to_numpy()),Plotly无法识别为时间序列类型,只能当作普通离散值处理,自动合并重复日期并省略标签。而官方示例直接使用datetime类型数组,Plotly能自动识别为时间轴并优化显示逻辑。 - 重复日期的标签压缩:你的数据中存在多个样本对应同一日期(如2022-11-17、2022-11-20均有多条记录),Plotly默认会合并相同日期的标签,导致X轴显示不完整。
解决方案
方案1:保留pandas datetime类型(推荐)
直接使用原pandas Series作为x轴输入,让Plotly正确识别时间序列:
# 不转numpy,直接使用原日期Series dates = X_reduced_df['EXTRACTION_DATE_SAMPLE'] fig = go.Figure(data=go.Heatmap( z=X_reduced_df[Heatmetrics].values, x=dates, y=Heatmetrics, colorscale='Viridis')) fig.update_layout( title='BWB Heatmap', xaxis=dict( nticks=50, tickformat='%Y-%m-%d', # 指定日期显示格式 tickangle=45 # 旋转标签避免重叠 ) ) fig.show()
方案2:强制显示所有日期(含重复值)
如果需要显示每个样本对应的日期(包括重复的),将X轴设为类别型:
# 将日期转为字符串作为类别 dates = X_reduced_df['EXTRACTION_DATE_SAMPLE'].dt.strftime('%Y-%m-%d') fig = go.Figure(data=go.Heatmap( z=X_reduced_df[Heatmetrics].values, x=dates, y=Heatmetrics, colorscale='Viridis')) fig.update_layout( title='BWB Heatmap', xaxis=dict( type='category', # 设置为类别轴 tickangle=45, tickmode='array', tickvals=dates, # 强制显示所有标签 ticktext=dates ) ) fig.show()
方案3:精确控制时间轴标签数量
保持时间轴特性,同时通过参数控制显示的标签数量:
dates = X_reduced_df['EXTRACTION_DATE_SAMPLE'] fig = go.Figure(data=go.Heatmap( z=X_reduced_df[Heatmetrics].values, x=dates, y=Heatmetrics, colorscale='Viridis')) fig.update_layout( title='BWB Heatmap', xaxis=dict( nticks=50, tickmode='linear', # 按线性间隔显示标签 tickformat='%Y-%m-%d', tickangle=45 ) ) fig.show()
内容的提问来源于stack exchange,提问作者Danny
相关产品推荐
相关产品推荐

