カテゴリー

px

【plotly&ガントチャート】px.timelineでGantt Chartsを作成

2021年12月8日

こんな人にオススメ

plotlyでガントチャートを作りたいんだけど、どうやってコードを書けばいい?

ということで、今回はplotlypx.timelineを使用してガントチャートを作成する。ガントチャートはプロジェクトなどの管理に使われるツリー状のグラフ。

日付を横軸・人やプロジェクト名を縦軸にしていつまでに何をするか・誰がするかを表すのに適したグラフだ。ガントチャートを作成できるサービスは存在するが、plotlyで自作することも可能。

plotlyだとガントチャートはpxを使用してグラフを作成する。ガントチャートに似た棒グラフについては以下。pxgoでそれぞれ記事にしている。

【plolty&棒グラフ】px.barでバーチャートを作成

こんな人にオススメ plotlyのpxで棒グラフを作成するにはどうしたらいい? ということで ...

続きを見る

【plotly&棒グラフ】go.Barでバーチャートを作成

こんな人にオススメ plotlyで棒グラフを描きたいんだけど、どうやったらいい? という ...

続きを見る

Plotly公式の「Gantt Charts in Python」にガントチャートの作成方法は書かれている。しかし、バージョン4.9以前に使われていたfigure factoryの解説もあり、px.timelineの解説は少なめ。

本記事では公式で書かれている内容よりも細かく解説しているので、 plotlypx.timelineを使ったガントチャートの作成方法を理解していただけると幸いだ。

python環境は以下。

  • Python 3.10.1
  • pandas 1.3.5
  • plotly 5.4.0
  • plotly-orca 3.4.2

運営者のメガネです。YouTubeTwitterInstagramも運営中。

自己紹介はこちらから、お問い合わせはこちらからお願いいたします。

運営者メガネ

作成したコード全文

下準備(import

import pandas as pd
import plotly.express as px
import plotly.io as pio

まずは下準備としてのimport関連。px.timelineの場合、データから自動的に日付を判断してくれるのでdatetimeimportは必要ないが、日付の編集などを行いたいときはimport datetimeなどでdatetimeimportすると良いだろう。

また、pxは基本的にpandasのデータフレームをベースにグラフを描くことになるのでpandasimportしている。

あとはpx本体とグラフ保存用のpio。グラフ保存に関しては以下。

plotlyでグラフを静止画として保存する際に出るポップアップ
【plotly&orca】plotlyで静止画保存(orca)

こんな人にオススメplotlyで画像を保存するときに色々と警告とかエラーが出てきて保ढ ...

続きを見る

シンプルにガントチャートを作成


まずはシンプルにガントチャートを作成。引数として使うのは以下。

  • data_frame: グラフ化したいデータの入ったデータフレーム(引数省略)
  • x_start: ガントチャートの開始日時
  • x_end: ガントチャートの終了日時
  • y: 縦軸の値

px.timelineは横軸を自動で時刻として認識してくれるので、以下に示すコードのようにデータフレームを作成しておけば勝手に横軸を整理してくれる。

もし上手く時刻に変換してくれなかったら、本記事の最後の方で解説する時刻の書式変更」の方法を参照いただきたい。

縦軸はTask列を指定し、各Job毎にグラフ化。あとはフォントサイズを上げてグラフを表示・保存した。簡単にグラフが描けるのがpxの魅力。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# pxでガントチャートを作成
# そのまま作成すると縦軸が上下逆さまに

# ガントチャートを作成するデータフレーム
df = pd.DataFrame([
    dict(
        Task='Job A',  # ジョブの名称
        Start='2022-01-01',  # 開始日
        Finish='2022-02-28',  # 終了日
    ),
    dict(
        Task='Job B',
        Start='2022-03-05',  # 開始日
        Finish='2022-04-15',  # 終了日
    ),
    dict(
        Task='Job C',
        Start='2022-02-20',  # 開始日
        Finish='2022-05-30',  # 終了日
    )
])
print(df)
#     Task       Start      Finish
# 0  Job A  2022-01-01  2022-02-28
# 1  Job B  2022-03-05  2022-04-15
# 2  Job C  2022-02-20  2022-05-30

fig = px.timeline(
    df,  # 使用するデータフレーム
    x_start='Start', x_end='Finish',  # 横軸の開始・終了の列名
    y='Task',  # 縦軸の列名
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフ保存
prefix = 'plotly-gantt-charts'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_simple"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

autorange='reversed'で縦軸の順番を自然に


さっきのグラフでも良かったんだけど、縦軸が上からJob C, B, Aと逆転している。データフレームではA, B, Cの順番だったからこれは気持ち悪い。

そんな時はfig.update_yaxesfig.update_yaxes(autorange='reversed')として縦軸の向きを逆転させたらいい。fig.update_yaxesなどのfig.updateシリーズについては以下の記事で詳しく解説している。

【plotly&fig作成と更新】add_traceやupdate_layoutの使い方

こんな人にオススメ plotlyでグラフを描く時にadd_traceとかupdate_layoutとかあるけど、これらは一体な ...

続きを見る

import pandas as pd
import plotly.express as px
import plotly.io as pio

# ガントチャートを作成するデータフレーム
df = pd.DataFrame([
    dict(
        Task='Job A',  # ジョブの名称
        Start='2022-01-01',  # 開始日
        Finish='2022-02-28',  # 終了日
    ),
    dict(
        Task='Job B',
        Start='2022-03-05',  # 開始日
        Finish='2022-04-15',  # 終了日
    ),
    dict(
        Task='Job C',
        Start='2022-02-20',  # 開始日
        Finish='2022-05-30',  # 終了日
    )
])
print(df)
#     Task       Start      Finish
# 0  Job A  2022-01-01  2022-02-28
# 1  Job B  2022-03-05  2022-04-15
# 2  Job C  2022-02-20  2022-05-30

fig = px.timeline(
    df,  # 使用するデータフレーム
    x_start='Start', x_end='Finish',  # 横軸の開始・終了の列名
    y='Task',  # 縦軸の列名
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# 縦軸の向きを逆にする
fig.update_yaxes(autorange='reversed')
fig.show()

# グラフ保存
prefix = 'plotly-gantt-charts'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_autorange_reversed"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

autorange=Falseにするとグラフ上部に空間が


なお、autorangeはデフォルトはTrueなんだけど、autorange=Falseにするとグラフ上部に空間ができる。このままだと見栄えが悪いのでautorange=Falseにしない方が良いだろう。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# autorange=Falseにする

# ガントチャートを作成するデータフレーム
df = pd.DataFrame([
    dict(
        Task='Job A',  # ジョブの名称
        Start='2022-01-01',  # 開始日
        Finish='2022-02-28',  # 終了日
    ),
    dict(
        Task='Job B',
        Start='2022-03-05',  # 開始日
        Finish='2022-04-15',  # 終了日
    ),
    dict(
        Task='Job C',
        Start='2022-02-20',  # 開始日
        Finish='2022-05-30',  # 終了日
    )
])
print(df)
#     Task       Start      Finish
# 0  Job A  2022-01-01  2022-02-28
# 1  Job B  2022-03-05  2022-04-15
# 2  Job C  2022-02-20  2022-05-30

fig = px.timeline(
    df,  # 使用するデータフレーム
    x_start='Start', x_end='Finish',  # 横軸の開始・終了の列名
    y='Task',  # 縦軸の列名
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# 自動範囲調節をオフにする
fig.update_yaxes(autorange=False)
fig.show()

# グラフ保存
prefix = 'plotly-gantt-charts'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_autorange_False"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

colorで色分けする

ここまでは全て同じ色でガントチャートを作成した。ただ、1色だけだと見づらいのでここでは色分けの方法を解説する。

Resource(人名、リソース)で色分け


まずはリソースで色分けする。ここでのリソースは人名で、Alexが2種類のTaskJob)に参加していることが一目でわかる。

指定方法は簡単で、データフレームにリソースを示す列を追加してpx.timelineの引数colorにデータフレームの列名(Resource)を指定するだけ。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# colorで色分けする(人名、リソース)

# ガントチャートを作成するデータフレーム
df = pd.DataFrame([
    dict(
        Task='Job A',  # ジョブの名称
        Start='2022-01-01', Finish='2022-02-28',  # 開始年と終了年
        Resource='Alex',  # リソース名
    ),
    dict(
        Task='Job B',
        Start='2022-03-05', Finish='2022-04-15',
        Resource='Alex',  # リソース名
    ),
    dict(
        Task='Job C',
        Start='2022-02-20', Finish='2022-05-30',
        Resource='Max',  # リソース名
    )
])

print(df)
#     Task       Start      Finish Resource
# 0  Job A  2022-01-01  2022-02-28     Alex
# 1  Job B  2022-03-05  2022-04-15     Alex
# 2  Job C  2022-02-20  2022-05-30      Max

fig = px.timeline(
    df,  # 使用するデータフレーム
    x_start='Start', x_end='Finish',  # 横軸の開始・終了の列名
    y='Task',  # 縦軸の列名
    color='Resource',  # 色分けをリソースにする
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# 縦軸の向きを逆にする
fig.update_yaxes(autorange='reversed')
fig.show()

# グラフ保存
prefix = 'plotly-gantt-charts'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_color_Resource"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

color_discrete_sequenceで色の変更


plotlyのデフォルトだと最初のプロットは青紫っぽい色、次の色は朱色っぽい赤色。この色を自由に変更するにはpx.timelineの引数color_discrete_sequenceを使う。

この引数で好みの色を配列で指定すると、その順番でチャートの色を変更してくれる。上のグラフではvioletorangeを指定。なお、今回は2色使用なので3色目のgreenは反映されない。

また、color_discrete_sequence=’red’すると以下のように1色目がredrを取ってしまうのでエラー。また、color_discrete_sequence=[’red’]のように1色だけの配列にすると色分けされなくなる。

ValueError: 
    Invalid value of type 'builtins.str' received for the 'color' property of bar.marker
        Received value: 'r'
import pandas as pd
import plotly.express as px
import plotly.io as pio

# color_discrete_sequenceで色を変更

# ガントチャートを作成するデータフレーム
df = pd.DataFrame([
    dict(
        Task='Job A',  # ジョブの名称
        Start='2022-01-01', Finish='2022-02-28',  # 開始年と終了年
        Resource='Alex',  # リソース名
    ),
    dict(
        Task='Job B',
        Start='2022-03-05', Finish='2022-04-15',
        Resource='Alex',  # リソース名
    ),
    dict(
        Task='Job C',
        Start='2022-02-20', Finish='2022-05-30',
        Resource='Max',  # リソース名
    )
])

print(df)
#     Task       Start      Finish Resource
# 0  Job A  2022-01-01  2022-02-28     Alex
# 1  Job B  2022-03-05  2022-04-15     Alex
# 2  Job C  2022-02-20  2022-05-30      Max

fig = px.timeline(
    df,  # 使用するデータフレーム
    x_start='Start', x_end='Finish',  # 横軸の開始・終了の列名
    y='Task',  # 縦軸の列名
    color='Resource',  # 色分けをリソースにする
    # 色の変更。余った色は反映されない
    color_discrete_sequence=('violet', 'orange', 'green')
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# 縦軸の向きを逆にする
fig.update_yaxes(autorange='reversed')
fig.show()

# # グラフ保存
prefix = 'plotly-gantt-charts'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_color_discrete_sequence"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

Completion_pct(完了度合い、数値)で色分け


リソース名だけじゃなくて完了度合いで色分けしたい時もあるだろう。その場合も同じようにpx.timelineの引数colorを使うだけ。

ただし、完了度合いの場合は数値になるので、自動でカラーバーとカラーバータイトルをつけてくれる。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# colorで色分けする(完了度合い)

# ガントチャートを作成するデータフレーム
df = pd.DataFrame([
    dict(
        Task='Job A',  # ジョブの名称
        Start='2022-01-01', Finish='2022-02-28',  # 開始年と終了年
        Completion_pct=50,  # 完了%
    ),
    dict(
        Task='Job B',
        Start='2022-03-05', Finish='2022-04-15',
        Completion_pct=25,  # 完了%
    ),
    dict(
        Task='Job C',
        Start='2022-02-20', Finish='2022-05-30',
        Completion_pct=75,  # 完了%
    )
])
print(df)
#     Task       Start      Finish  Completion_pct
# 0  Job A  2022-01-01  2022-02-28              50
# 1  Job B  2022-03-05  2022-04-15              25
# 2  Job C  2022-02-20  2022-05-30              75

fig = px.timeline(
    df,  # 使用するデータフレーム
    x_start='Start', x_end='Finish',  # 横軸の開始・終了の列名
    y='Task',  # 縦軸の列名
    color='Completion_pct',  # 色分けを完了度合いにする
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# 縦軸の向きを逆にする
fig.update_yaxes(autorange='reversed')
fig.show()

# グラフ保存
prefix = 'plotly-gantt-charts'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_color_Completion_pct"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

color_continuous_scaleでカラースケールを変更


カラーバーの色合いを変更することももちろん可能。上のグラフではカラースケールのJetという色を使用してカラーバーの色を変更した。

カラースケールに関してはPlotly公式の「Built-in Continuous Color Scales in Python」で詳しく解説されている。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# color_continuous_scaleでカラースケールの変更

# ガントチャートを作成するデータフレーム
df = pd.DataFrame([
    dict(
        Task='Job A',  # ジョブの名称
        Start='2022-01-01', Finish='2022-02-28',  # 開始年と終了年
        Completion_pct=50,  # 完了%
    ),
    dict(
        Task='Job B',
        Start='2022-03-05', Finish='2022-04-15',
        Completion_pct=25,  # 完了%
    ),
    dict(
        Task='Job C',
        Start='2022-02-20', Finish='2022-05-30',
        Completion_pct=75,  # 完了%
    )
])

fig = px.timeline(
    df,  # 使用するデータフレーム
    x_start='Start', x_end='Finish',  # 横軸の開始・終了の列名
    y='Task',  # 縦軸の列名
    color='Completion_pct',  # 色分けを完了度合いにする
    color_continuous_scale='Jet'  # 色の付け方をJetに変更
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# 縦軸の向きを逆にする
fig.update_yaxes(autorange='reversed')
fig.show()

# グラフ保存
prefix = 'plotly-gantt-charts'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_color_Completion_pct_Jet"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

同じ人は同じ行に配置


同じ人を同じ行に配置することも可能。上のグラフではAlexが2種類のJobを請け負っているので、同じ行に配置されるように縦軸をResourceにした。

また、px.timelineの引数colorにもResourceを使用することで色分けもしてくれるから、さらに見やすくなる。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# colorで色分け(人名、同じ人は同じ行に)

# ガントチャートを作成するデータフレーム
df = pd.DataFrame([
    dict(
        Task='Job A',  # ジョブの名称
        Start='2022-01-01', Finish='2022-02-28',  # 開始年と終了年
        Resource='Alex',  # リソース名
    ),
    dict(
        Task='Job B',
        Start='2022-03-05', Finish='2022-04-15',
        Resource='Alex',  # リソース名
    ),
    dict(
        Task='Job C',
        Start='2022-02-20', Finish='2022-05-30',
        Resource='Max',  # リソース名
    )
)

fig = px.timeline(
    df,  # 使用するデータフレーム
    x_start='Start', x_end='Finish',  # 横軸の開始・終了の列名
    y='Resource',  # 縦軸の列名をリソースに変更
    color='Resource',  # 色分けをリソースにする
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフ保存
prefix = 'plotly-gantt-charts'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_y_Resource"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

autorange='reversed'だと凡例と縦軸の向きが逆に


注意点としてはautorange='reversed'にすると凡例と縦軸の向きが逆になってしまうこと。シンプルにガントチャートを作成するときにはreversedにする方が良かったが、ここではその逆。ややこしい。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# autorange='reversed'にすると凡例と縦軸の向きが逆に

# ガントチャートを作成するデータフレーム
df = pd.DataFrame([
    dict(
        Task='Job A',  # ジョブの名称
        Start='2022-01-01', Finish='2022-02-28',  # 開始年と終了年
        Resource='Alex',  # リソース名
    ),
    dict(
        Task='Job B',
        Start='2022-03-05', Finish='2022-04-15',
        Resource='Alex',  # リソース名
    ),
    dict(
        Task='Job C',
        Start='2022-02-20', Finish='2022-05-30',
        Resource='Max',  # リソース名
    )
])

fig = px.timeline(
    df,  # 使用するデータフレーム
    x_start='Start', x_end='Finish',  # 横軸の開始・終了の列名
    y='Resource',  # 縦軸の列名をリソースに変更
    color='Resource',  # 色分けをリソースにする
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# 縦軸の向きを逆にすると凡例と縦軸が逆になる
fig.update_yaxes(autorange='reversed')
fig.show()

# グラフ保存
prefix = 'plotly-gantt-charts'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_y_Resource_recersed"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

横軸の時間書式を変更


これまでは英語表記の時間軸でグラフを作成した。Mar 2022といった具合だ。ただ、この書き方だと慣れていないとぱっと見で理解しにくい。

上のグラフのように時刻を日本語に変更するには、fig.update_xaxesの引数tickformatで年(%Y)、月(%m)、日(%d)の間に年月日を入れたらいい。

fig.update_xaxesfig.update_layout(xaxis=dict(tickformat...))という書き方でも可能。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# 横軸の時間書式を変更

# ガントチャートを作成するデータフレーム
df = pd.DataFrame([
    dict(
        Task='Job A',  # ジョブの名称
        Start='2022-01-01', Finish='2022-02-28',  # 開始年と終了年
        Resource='Alex',  # リソース名
    ),
    dict(
        Task='Job B',
        Start='2022-03-05', Finish='2022-04-15',
        Resource='Alex',  # リソース名
    ),
    dict(
        Task='Job C',
        Start='2022-02-20', Finish='2022-05-30',
        Resource='Max',  # リソース名
    )
])

fig = px.timeline(
    df,  # 使用するデータフレーム
    x_start='Start', x_end='Finish',  # 横軸の開始・終了の列名
    y='Task',  # 縦軸の列名
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# 横軸の書式を変更
fig.update_xaxes(tickformat='%Y年%m月%d日')
# 縦軸の向きを逆にする
fig.update_yaxes(autorange='reversed')
fig.show()

# グラフ保存
prefix = 'plotly-gantt-charts'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_tickformat"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

rangeselectorrangesliderを追加


レイアウトにrangeselectorを追加することで、簡単に表示範囲を変更することができる。さらにrangesliderを使うことで全体の中でどの部分を拡大しているのかもわかりやすい。rangeselector, rangesliderについては以下の記事を参照。

【plotly&rangeslider/rangeselector】レンジスライダーとレンジセレクターで時系列を見やすく

こんな人にオススメ plotlyの時系列のグラフで特定の特定の期間をうまく表現できない{ ...

続きを見る

ここではrangeselectorで14日=2週間、1ヶ月、2ヶ月、全体表示のボタンを追加した。rangeselectorにはweekがないので、週単位にしたいときは日換算しないといけない。

import pandas as pd
import plotly.express as px
import plotly.io as pio

# ガントチャートを作成するデータフレーム
df = pd.DataFrame([
    dict(
        Task='Job A',  # ジョブの名称
        Start='2022-01-01', Finish='2022-02-28',  # 開始年と終了年
        Resource='Alex',  # リソース名
    ),
    dict(
        Task='Job B',
        Start='2022-03-05', Finish='2022-04-15',
        Resource='Alex',  # リソース名
    ),
    dict(
        Task='Job C',
        Start='2022-02-20', Finish='2022-05-30',
        Resource='Max',  # リソース名
    )
])

fig = px.timeline(
    df,  # 使用するデータフレーム
    x_start='Start', x_end='Finish',  # 横軸の開始・終了の列名
    y='Task',  # 縦軸の列名
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# 横軸のレイアウト修正
fig.update_xaxes(
    # 横軸の書式を変更
    tickformat='%Y年%m月%d日',
    # グラフ上にレンジセレクターを追加
    rangeselector=dict(
        buttons=list([
            # 14日間=2週間
            dict(
                count=14,  # 数値
                label='2w',  # ボタンラベル
                step='day',  # 単位
                stepmode='backward'  # 現時点より以前
            ),
            # 1ヶ月
            dict(
                count=1,
                label='1m',
                step='month',
                stepmode='backward'
            ),
            # 2ヶ月
            dict(
                count=2,
                label='2m',
                step='month',
                stepmode='backward'
            ),
            dict(step='all')
        ])
    ),
    # グラフ下にレンジスライダーを追加
    rangeslider=dict(visible=True),
)

# 縦軸の向きを逆にする
fig.update_yaxes(autorange='reversed')
fig.show()

# グラフ保存
prefix = 'plotly-gantt-charts'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_rangeselector_rangeslider"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

facet_colでサブプロット風に


最後にpx特有のサブプロットのようなグラフの描き方facetを使用する。facetについては以下の記事を参照。

【px&facet】plotly.expressでsubplotsを描く

こんな人にオススメ plotly.express、pxでsubplotsを作成したいけどどうしたらいい? make_subplotsとか使わな{ ...

続きを見る

facet_colで列の分割を、facet_rowで行の分割をデータフレームの列名で指定可能。ただし、分割数は列方向でしか指定できないからfacet_colを使用する方がわかりやすい。

また、以下の引数も追加してより見やすいようにガントチャートを作成。fig.update_tracestextposition, insidetextanchorを設定することでpx.timelineの引数textを置く位置を決めた。

  • opacity: 不透明度
  • title: グラフタイトル
  • hover_data: マウスオーバー時に出る情報
  • text: バー上に表記する内容

今回は以下のcsvデータを予め作成し、これを読み込んでグラフ化する。idea列はこのリソースや期間はどうですかっていうアイデアの意味で作成。

このideaごとにfacetでサブプロットのガントチャートを作成した。

Task Start Finish Resource Completion_pct idea
JobA 2022/1/1 2022/2/28 Alex 50 1
JobB 2022/3/5 2022/4/15 Alex 25 1
JobC 2022/2/20 2022/5/30 Max 75 1
JobA 2022/1/26 2022/3/25 Bob 50 2
JobB 2022/4/11 2022/5/10 Daniel 25 2
JobC 2022/3/17 2022/6/24 Mike 75 2
JobA 2022/1/31 2022/3/30 Nick 50 3
JobB 2022/4/4 2022/5/15 Ben 25 3
JobC 2022/3/22 2022/6/29 Max 75 3
JobA 2022/1/12 2022/4/4 Alex 50 4
JobB 2022/4/9 2022/5/20 Ben 25 4
JobC 2022/3/27 2022/7/14 Nick 75 4
import pandas as pd
import plotly.express as px
import plotly.io as pio

# データの読み込み
# parse_datesで時間に変換する列を選択
df = pd.read_csv('facet.csv', parse_dates=[1, 2])
print(df)

#     Task      Start     Finish Resource  Completion_pct  idea
# 0   JobA 2022-01-01 2022-02-28     Alex              50     1
# 1   JobB 2022-03-05 2022-04-15     Alex              25     1
# 2   JobC 2022-02-20 2022-05-30      Max              75     1
# 3   JobA 2022-01-26 2022-03-25      Bob              50     2
# 4   JobB 2022-03-30 2022-05-10   Daniel              25     2
# 5   JobC 2022-03-17 2022-06-24     Mike              75     2
# 6   JobA 2022-01-31 2022-03-30     Nick              50     3
# 7   JobB 2022-04-04 2022-05-15      Ben              25     3
# 8   JobC 2022-03-22 2022-06-29      Max              75     3
# 9   JobA 2022-02-05 2022-04-04     Alex              50     4
# 10  JobB 2022-04-09 2022-05-20      Ben              25     4
# 11  JobC 2022-03-27 2022-07-04     Nick              75     4

fig = px.timeline(
    df,  # 使用するデータフレーム
    x_start='Start', x_end='Finish',  # 横軸の開始・終了の列名
    y='Task',  # 縦軸の列名
    color='Resource',
    opacity=0.5,  # 不透明度を下げる
    title='Gantt Charts',  # グラフタイトル
    hover_data=df,  # ホバーで表示する情報はデータフレームの全情報
    text='Resource',  # バー上に文字を追加
    facet_col='idea',  # どの列で分割するか
    facet_col_wrap=2,  # 分割列数
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
# 2022/1/1のように0埋めを消す
fig.update_xaxes(tickformat='%Y/%-m/%-d')
# px.timelineの引数textを置く位置を内側の中央に変更
fig.update_traces(textposition='inside', insidetextanchor='middle')
fig.show()

# グラフ保存
prefix = 'plotly-gantt-charts'  # 保存ファイル名の接頭辞
save_name = f"{prefix}_facet_col"
pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
pio.write_html(fig, f"{save_name}.html")
pio.write_image(fig, f"{save_name}.png")

プロジェクト管理に役立つ?

ということで、今回はplotlypx.timelineを使用してガントチャートを作成した。ガントチャート自体はプロジェクトの管理に使われているからメジャーなもの。

一方で、メジャーだからこそわざわざplotlyで作成しなくても専用のアプリとかサービスがあるはず。なんならシンプルなグラフだからExcelでもいい。

まあ、これを応用してWebアプリに組み込むとかそういうのができるかもしれないから知っておいて損はない。と思う。

関連記事

【plolty&棒グラフ】px.barでバーチャートを作成

こんな人にオススメ plotlyのpxで棒グラフを作成するにはどうしたらいい? ということで ...

続きを見る

【plotly&px.scatter】pxでの散布図の描き方

こんな人にオススメ plotlyの中にpxってのがあるけど、これで散布図(scatter)を描くにはど ...

続きを見る

【plotly&3D】px.scatter_3dとpx.line_3Dで3Dグラフを作成

こんな人にオススメ plotlyのpxで3Dグラフを描くのってどうしたらいい? ということで、今 ...

続きを見る

【px&animation】plotly.expressでアニメーションのグラフを作成

こんな人にオススメ plotlyでアニメーションができるらしいけどどうやるの? Plotly公式のӎ ...

続きを見る

【plotly&棒グラフ】go.Barでバーチャートを作成

こんな人にオススメ plotlyで棒グラフを描きたいんだけど、どうやったらいい? という ...

続きを見る

【plotly&go.Scatter】plotlyの散布図グラフの描き方

こんな人にオススメ plotlyのとっかかりとして散布図(scatter)を描きたいけど、どうやっӗ ...

続きを見る

【plotly&fill】px.areaで積み上げ塗りつぶし

こんな人にオススメ pxで塗りつぶしをするのってどうやったらいい?goだと結構面倒だ ...

続きを見る

【plotly&px.scatter】pxでの散布図の描き方

こんな人にオススメ plotlyの中にpxってのがあるけど、これで散布図(scatter)を描くにはど ...

続きを見る

【plotly&Scattergl】大量のデータをplotlyで軽くグラフ化

こんな人にオススメ plotlyを使ってグラフを描いているんだけど、データが大量にある{ ...

続きを見る

【plotly&config】グラフのツールバーを編集する

こんな人にオススメ plotlyでグラフを作成すると右上に灰色のバーみたいなものが出て{ ...

続きを見る

スマホ

2023/1/21

【Galaxy S22 Ultraレビュー】これが最高峰

こんな人におすすめ 2022年最強のスマホGalaxy S22 Ultraって実際使った感じどうなの ...

完全ワイヤレスイヤホン(TWS)

2023/1/15

【SENNHEISER MOMENTUM True Wireless 3レビュー】高レベルでバランス型の高音質イヤホン

こんな人におすすめ SENNHEISER MOMENTUM True Wireless 3って実際のところどうなの? 評判は良い ...

完全ワイヤレスイヤホン(TWS)

2023/1/14

【SONY WF-1000XM4 vs SENNHEISER MTW3】MTW3を選んだ決定的な3つの理由

こんな人におすすめ 執筆者は「SONY WF-1000XM4」「SENNHEISER MOMENTUM True Wireless 3」両方を持っている ...

スマホ

2023/1/15

【楽天モバイル×povo2.0の併用】月1,000円の保険付きデュアルSIM運用

こんな人におすすめ 楽天モバイルとpovo2.0のデュアルSIM運用って実際のとこ ...

マウス

2023/1/5

【Logicool MX ERGOレビュー】疲れない作業効率重視トラックボールマウス

こんな人におすすめ トラックボールマウスの王道Logicool MX ERGOが気になるけどऩ ...

マウス

2023/1/14

【Logicool MX ERGOカスタム】Logi Optionsのジェスチャーボタン設定内容

こんな人におすすめ Logicool MX ERGOをもっと上手に効率的に使いこなしたい。 ボ| ...

生活に役立つ

2023/1/8

【メガネ厳選】クソ便利に使っているサービスやアイテム達

このページでは執筆者「メガネ」が実際に使って便利だと感じているサ ...

完全ワイヤレスイヤホン(TWS)

2023/1/15

【SONY WF-1000XM4レビュー】神とゴミのハーフ&ハーフ

こんな人におすすめ SONYのフラグシップモデル「SONY WF-1000XM4」ってどれくらい性 ...

スイッチボット

2023/1/14

【SwitchBot Hub Mini】アプリにないエアコンなどの家電をその他で登録する方法

こんな人におすすめSwitchBot Hub Miniに我が家のエアコンを登録したいけど、SwitchBotア ...

Pythonを学びたいけど独学できる時間なんてない人へのすゝめ

執筆者は大学の研究室・大学院にて独学でPythonを習得した。

でも社会人になったら独学で行うには時間も体力もなくて大変だ。

時間がない社会人だからこそプロの教えを乞うのが効率的。

ここでは色んなタイプに合ったプログラミングスクールの紹介をする。

  • この記事を書いた人

メガネ

ベンチャー企業のWebエンジニア駆け出し。独学のPythonで天文学系の大学院を修了→新卒を1.5年で辞める→転職→今に至る。
常時金欠のガジェット好きでM1 MacBook Pro x Galaxy S22 Ultraの狂人。

自己紹介と半生→変わって楽しいの繰り返し レビュー依頼などお問い合わせ Twitter@m_ten_pa

-px
-, , , ,