如何在绘图轴上只保留时间

2024-10-02 22:30:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着用plotly和袖扣创建一个图表,在xaxis上有日期,在primary y上有一些数量,在secondary y上有时间

数据如下所示:

        automatic   manual  time
2019-02-25  206.0   1206.0  2019-02-26 16:58:09
2019-02-26  225.0   136.0   2019-02-27 08:33:49
2019-02-27  213.0   554.0   2019-02-28 07:25:19
2019-02-28  244.0   103.0   2019-03-01 07:32:37
2019-03-01  102.0   119.0   2019-03-04 12:06:37

该图的设置如下:

fig = go.Figure(**cf.tools.merge_figures([
    df.figure(columns=["automatic", "manual"], kind="bar", barmode="stack"),
    df.figure(columns=["time"])
])).set_axis(["time"], side="right")

获得所需图形的唯一方法是将df.time列中每个日期的日期部分设置为相同的任意日期,如下所示:

df.loc[:, "time"] = df.time.apply(lambda d: d.replace(year=1967, month=1, day=1))

然而,这样我得到了错误的悬停文本和任意日期显示在底部的第二个y

我尝试手动设置yaxis2的范围,如下所示:

sotimes = [d for d in df.time.tolist() if not pd.isnull(d)]
fig["layout"].update({"yaxis2": {"range": [f"{min(sotimes):%H:%M:%S}", f"{max(sotimes):%H:%M:%S}"]}})

奇怪的是,这导致yaxis2也是一个日期范围。你知道吗

我还尝试将df.time转换为时间,或者作为字符串,或者作为日期时间.time像这样:

df.loc[:, "time"] = df.time.apply(
    lambda d: d.time() if not pd.isnull(d) else pd.NaT)
df.loc[:, "time"] = df.time.apply(
    lambda d: f"{d:%H:%M:%S}" if not pd.isnull(d) else "")

这两种情况都会导致yaxis2完全没有顺序,时间是按照它们在df.time中出现的顺序显示的。你知道吗


编辑1-添加完整代码

import cufflinks as cf
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
import pandas as pd


# plotly stuff
cf.go_offline()

dct = {
    "date": ["2019-02-25", "2019-02-26", "2019-02-27", "2019-02-28", "2019-03-01"],
    "auto": [206, 225, 213, 244, 102],
    "manual": [1206, 136, 554, 103, 119],
    'time': [pd.Timestamp(2019, 2, 26, 16, 58, 9), pd.Timestamp(2019, 2, 27, 8, 33, 49),
             pd.Timestamp(2019, 2, 28, 7, 25, 19), pd.Timestamp(2019, 3, 1, 7, 32, 37),
             pd.Timestamp(2019, 3, 4, 12, 6, 37)]
}
df = pd.DataFrame(dct).set_index("date")
df.loc[:, "time"] = df.time.apply(lambda d: d.replace(year=1967, month=1, day=1))

fig = go.Figure(**cf.tools.merge_figures([
    df.figure(columns=["auto", "manual"], kind="bar", barmode="stack"),
    df.figure(columns=["time"])
])).set_axis(["time"], side="right")
# sotimes = [d for d in df.time.tolist() if not pd.isnull(d)]
# fig["layout"].update({"yaxis2": {"range": [f"{min(sotimes):%H:%M:%S}", f"{max(sotimes):%H:%M:%S}"]}})
plot(fig)

Tags: columnsgodftime时间figplotlymanual