【问题标题】:How to keep only time on plotly graph axis如何在绘图轴上只保留时间
【发布时间】:2019-05-21 08:13:05
【问题描述】:

我正在尝试创建一个图表,其中包含 x 轴上的日期、主要 y 上的一些金额和次要 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 转换为仅时间,可以是字符串或 datetime.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 中出现的顺序显示。


EDIT 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)

【问题讨论】:

  • 您能否提供整个代码的示例,可能在 google collab 上或在您的帖子底部?
  • 一切都在那里,除了plot(fig) 这是最后一步。 df 在结构上与我发布的示例数据相同,只是记录更多。还是说进口也是?
  • 是的,只是为了快速、结构化、快速地了解您当前的状态。 :)
  • 完成 - 希望它更清楚;)
  • 现在看起来很完美!

标签: python pandas plotly


【解决方案1】:

这不是整个问题的答案,而是按照您希望的方式创建一个工作图。使用将每个日期时间实例设置为相同日期的方法,您可以使用以下方法调整刻度标签:

    fig["layout"].update({"yaxis2": {"tickformat": "%H:%M"}})

【讨论】:

  • 如果您可以分享任何有助于更好地理解解决方案的文档链接,那就太好了。也感谢代码解释。
猜你喜欢
  • 2016-06-24
  • 2020-09-18
  • 1970-01-01
  • 1970-01-01
  • 2014-05-31
  • 2018-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多