【问题标题】:Fixed bar width/thickness in plotly.express.timeline修复了 plotly.express.timeline 中的条形宽度/厚度
【发布时间】:2021-10-01 15:58:05
【问题描述】:

我正在使用 Plotly Express 绘制甘特图。

我事先不知道水平线的数量(“任务”的数量)。

我希望钢筋始终保持相同的厚度。 (我相信属性是宽度,但由于条是水平的,“宽度”可能不明确。)

当直接绘制图形时,它会占用页面上的整个空间,当调整页面大小时,条形会相应地改变大小。

import datetime as dt
import plotly.express as px


data = [
    {'Task': '1-2', 'Start': '2021-09-26', 'Finish': '2021-09-27', 'Resource': 'R1'},
    {'Task': '2-1', 'Start': '2021-09-23', 'Finish': '2021-09-24', 'Resource': 'R2'},
    {'Task': '2-2', 'Start': '2021-09-26', 'Finish': '2021-09-27', 'Resource': 'R2'},
    {'Task': '3-1', 'Start': '2021-09-30', 'Finish': '2021-10-01', 'Resource': 'R3'},
    {'Task': '3-2', 'Start': '2021-11-26', 'Finish': '2021-11-27', 'Resource': 'R3'},
]

fig = px.timeline(
    data,
    x_start="Start",
    x_end="Finish",
    y="Resource",
)

fig.show()

每个条形都有一个宽度属性,但它控制条形使用的允许空间的多少,因此它实际上并没有固定宽度。

一个便宜的技巧是根据行数设置图形高度,但必须考虑周围环境(图例、标题等),因此它不是真正的线性。无论如何,这充其量只是一个遗憾的解决方法。

当我将图表集成到类似页面中时

Python 代码

return plotly.io.to_json(fig)

HTML 页面

<script src="https://cdn.plot.ly/plotly-2.0.0.min.js"></script>
<script type="text/javascript">

let graph = {{ gantt_json|safe }};
Plotly.newPlot('gantt_graph', graph, {});

</script>

图表不会占据整个页面,但随着条数的变化,条的宽度仍然会发生变化。


所以我可以控制图形的总大小,以及每个条相对于其允许空间的宽度,但我似乎无法找到以像素为单位获得固定宽度的方法。

(我认为 this issueclosing PR 会有所帮助,但他们没有。)

我错过了什么吗?

【问题讨论】:

标签: python plotly plotly-python gantt-chart


【解决方案1】:
  • 横向思考这可以通过控制 yaxisdomain 来实现
  • 有模拟数据,会生成随机数量的时间线
  • 根据时间线数设置最小值
import pandas as pd
import numpy as np
import plotly.express as px
T = 8
data = pd.DataFrame(
    {
        "Start": pd.date_range("1-jan-2021", freq="2D", periods=T),
        "Finish": pd.date_range("14-jan-2021", freq="2D", periods=T),
        "Resource": np.random.choice(
            [chr(i) for i in range(ord("A"), ord("A") + T)], T
        ),
    }
)
color_map = {chr(ord("A") + i): px.colors.qualitative.Alphabet[i%len(px.colors.qualitative.Alphabet)] for i in range(T)}
fig = px.timeline(
    data,
    x_start="Start",
    x_end="Finish",
    y="Resource",
    color="Resource",
    color_discrete_map=color_map,
    #    height=10 * len(data)  # This sucks
)
fig.update_xaxes(
    side="top",
    dtick="D1",
    tickformat="%e\n%b\n%Y",
    ticklabelmode="period",
    tickangle=0,
    fixedrange=True,
)
fig.update_yaxes(
    title="",
    tickson="boundaries",
    fixedrange=True,
)
BARHEIGHT = .1
fig.update_layout(
    yaxis={"domain": [max(1 - (BARHEIGHT * len(fig.data)), 0), 1]}, margin={"t": 0, "b": 0}
)

【讨论】:

  • 感谢您的回答。我一直在尝试这个,但我认为它不能满足我的要求。 BARHEIGHT 似乎是实际使用的图形高度部分。 firht 上的传说仍然使用整个八个。将BARHEIGHT 设置为 0.8 会使图形(所有条形图)使用 80% 的可用空间,但当窗口大小调整或条形图数量发生变化时,条形图的粗细仍然会发生变化。我想要的是将条形厚度强制为给定数量的像素。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-19
  • 1970-01-01
  • 2014-01-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多