You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bokeh Y轴时间显示异常:微秒转分钟及图表无线条解决方案

解决Bokeh Y轴时间(VARCHAR类型)显示问题的步骤

这个问题我之前也碰到过,核心卡点在于Bokeh的时间轴只认标准的datetime类型(或对应的毫秒级时间戳),而你从MySQL读出来的varchar字符串,Bokeh根本识别不出这是时间数据——自然不会应用格式化规则,甚至连线条都画不出来。下面给你一步步拆解解决方案:

1. 先把VARCHAR时间字符串转成Python datetime对象

不管用pandas还是原生MySQL驱动读数据,第一步必须完成字符串到datetime的转换。假设你数据库里的时间格式是"YYYY-MM-DD HH:MM:SS"(比如"2024-05-20 14:30:00"),用pandas的话可以这么写:

import pandas as pd
from sqlalchemy import create_engine

# 连接MySQL并读取数据
engine = create_engine('mysql+pymysql://user:password@host/db_name')
df = pd.read_sql("SELECT time_col, value_col FROM your_table", engine)

# 把varchar类型的时间转成datetime对象
df['datetime_time'] = pd.to_datetime(df['time_col'], format="%Y-%m-%d %H:%M:%S")

如果不用pandas,用mysql-connector原生驱动的话,就用Python标准库的datetime.strptime逐个转换:

import datetime
import mysql.connector

conn = mysql.connector.connect(user='user', password='password', host='host', database='db_name')
cursor = conn.cursor()
cursor.execute("SELECT time_col, value_col FROM your_table")
raw_data = cursor.fetchall()

# 转换时间字符串为datetime对象
processed_data = []
for time_str, value in raw_data:
    dt = datetime.datetime.strptime(time_str, "%Y-%m-%d %H:%M:%S")
    processed_data.append( (dt, value) )

注意:一定要严格匹配你数据库里时间字符串的实际格式!比如如果是"MM/DD/YYYY HH:MM",就把format改成"%m/%d/%Y %H:%M",否则转换会报错。

2. 转成Bokeh兼容的毫秒级时间戳

Bokeh内部处理时间时,用的是从1970-01-01 UTC开始的毫秒级时间戳(整数类型),所以需要把datetime对象转成这个格式:
用pandas的话:

# pandas的datetime是纳秒级,除以1e6得到毫秒级时间戳
df['bokeh_time'] = df['datetime_time'].astype('int64') // 10**6

原生Python的话:

import time

processed_data_bokeh = []
for dt, value in processed_data:
    # 转成毫秒级时间戳
    timestamp_ms = int(time.mktime(dt.timetuple()) * 1000)
    processed_data_bokeh.append( (timestamp_ms, value) )

3. 配置Bokeh图表的Y轴

现在可以绘图了,关键要指定Y轴为datetime类型,并设置DatetimeTickFormatter:

from bokeh.plotting import figure, show
from bokeh.models import DatetimeTickFormatter

p = figure(
    y_axis_type="datetime",  # 重中之重:指定Y轴为时间类型
    title="时间数据Y轴示例",
    x_axis_label="X轴标签",
    y_axis_label="时间(分钟格式)"
)

# 绘制线条,用转换后的bokeh_time作为Y值
p.line(x=df.index, y=df['bokeh_time'], line_width=2)

# 配置Y轴的时间格式,按需调整显示规则
p.yaxis.formatter = DatetimeTickFormatter(
    minutes=["%M:%S", "%H:%M"],  # 轴范围是分钟级时的显示格式
    hours=["%H:%M", "%Y-%m-%d"],  # 轴范围是小时级时的显示格式
    days=["%Y-%m-%d"]  # 更大时间范围时的显示格式
)

show(p)

常见问题排查

  • 如果线条不显示:检查转换后的bokeh_time是否有有效值,比如有没有NaN或者异常大/小的数值;同时确认x和y的数据长度一致。
  • 如果格式化还是不生效:务必确认已经设置了y_axis_type="datetime"——没有这行的话,Bokeh会把Y轴当成普通数值轴,DatetimeTickFormatter完全不会起作用。
  • 如果时间显示有偏移:注意时区问题,MySQL里的时间如果是本地时区,转换时可能需要调整为UTC,或者在DatetimeTickFormatter里指定timezone参数。

内容的提问来源于stack exchange,提问作者Meh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:00:08