カテゴリー

px

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

2021年12月11日

こんな人にオススメ

plotlypxで棒グラフを作成するにはどうしたらいい?

ということで、今回はplotlypx.barを使用して棒グラフを作成する方法を解説する。以下の記事でplotly.graph_objectsgoを使用した棒グラフの記事を書いている。

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

こんな人にオススメ plotlyで棒| ...

続きを見る

pxの場合、goに比べてサクッとそれなりのグラフを作成することができるので重宝する。pxに関した記事は以下。

Plotly全般

【plotly&pattern】棒グラフとかのパターンまとめ

2022/8/19

こんな人にオススメ plotlyの棒| ...

px

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

2022/8/19

こんな人にオススメ plotlyのpxで ...

px

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

2022/8/19

こんな人にオススメ plotlyでガ} ...

px

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

2022/8/19

こんな人にオススメ plotlyの中{ ...

なお、本記事はplotly公式「Bar Charts in Python」のpx.barの解説をベースとしている。

python環境は以下・

  • Python 3.10.1
  • matplotlib 3.5.1
  • plotly 5.4.0
  • plotly-orca 3.4.2

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

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

運営者メガネ

作成したコード全文

下準備

import matplotlib.cm as cm
import plotly
import plotly.express as px
import plotly.io as pio

まずは下準備としてのimport関連。基本はplotly.express, pxとで完結するが、カラースケール使用時にmatplotlibを用いる。後述する。

また、pioはグラフ保存用のライブラリで、以下で解説している。

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

こんな人にオススメplotlyで画ࠔ ...

続きを見る

配列から棒グラフを作成


まずは配列から棒グラフを作成する方法。実はpxでは配列を使った棒グラフの作成はあまりしない。基本はpandasのデータフレームの列名を使って棒グラフを作成する。ただ、いちいちデータフレームを作成するのが面倒って時もあるだろうからここで紹介しておく。

pxで棒グラフを作成するにはpx.barを使うが、その引数xに横軸の配列を、yに縦軸の配列を入れたらいい。あとはfig.show()でグラフを表示するとグラフが表示される。

なお、デフォルトのフォントサイズだと小さめなのでここではupdate_layoutでフォントサイズを変更している。update_layoutなどについては以下。

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

こんな人にオススメ plotlyでグ} ...

続きを見る

最後にグラフを保存するためpioで設定をしている。保存ファイル形式はhtmlとpng。

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

# 配列から棒グラフを作成
x = (0, 1, 2, 3, 10)  # 横軸の値
y = (1, 3, 5, 7, 10)  # 縦軸の値

fig = px.bar(x=x, y=y)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフの保存
prefix = 'plotly-px-bar'  # ファイル保存名の接頭辞
save_name = f"{prefix}_array"
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")

データフレームから棒グラフを作成


次はデータフレームからグラフを作成。使用するデータはpxの中のギャップマインダーのもの。これの国、年、人口のデータより棒グラフを作成した

以下のデータフレームが全体データ。ここからカナダだけを抽出した。

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

df = px.data.gapminder()
print(df)
#           country continent  year  ...   gdpPercap  iso_alpha  iso_num
# 0     Afghanistan      Asia  1952  ...  779.445314        AFG        4
# 1     Afghanistan      Asia  1957  ...  820.853030        AFG        4
# 2     Afghanistan      Asia  1962  ...  853.100710        AFG        4
# 3     Afghanistan      Asia  1967  ...  836.197138        AFG        4
# 4     Afghanistan      Asia  1972  ...  739.981106        AFG        4
# ...           ...       ...   ...  ...         ...        ...      ...
# 1699     Zimbabwe    Africa  1987  ...  706.157306        ZWE      716
# 1700     Zimbabwe    Africa  1992  ...  693.420786        ZWE      716
# 1701     Zimbabwe    Africa  1997  ...  792.449960        ZWE      716
# 1702     Zimbabwe    Africa  2002  ...  672.038623        ZWE      716
# 1703     Zimbabwe    Africa  2007  ...  469.709298        ZWE      716

# [1704 rows x 8 columns]

データの抽出方法は色んな方法があるけど、ここでは.queryを使用し、国名countryがカナダCanadaであるデータのみを抽出。

data_canada = df.query("country == 'Canada'")
print(data_canada)
#     country continent  year  lifeExp       pop    gdpPercap iso_alpha  iso_num
# 240  Canada  Americas  1952   68.750  14785584  11367.16112       CAN      124
# 241  Canada  Americas  1957   69.960  17010154  12489.95006       CAN      124
# 242  Canada  Americas  1962   71.300  18985849  13462.48555       CAN      124
# 243  Canada  Americas  1967   72.130  20819767  16076.58803       CAN      124
# 244  Canada  Americas  1972   72.880  22284500  18970.57086       CAN      124
# 245  Canada  Americas  1977   74.210  23796400  22090.88306       CAN      124
# 246  Canada  Americas  1982   75.760  25201900  22898.79214       CAN      124
# 247  Canada  Americas  1987   76.860  26549700  26626.51503       CAN      124
# 248  Canada  Americas  1992   77.950  28523502  26342.88426       CAN      124
# 249  Canada  Americas  1997   78.610  30305843  28954.92589       CAN      124
# 250  Canada  Americas  2002   79.770  31902268  33328.96507       CAN      124
# 251  Canada  Americas  2007   80.653  33390141  36319.23501       CAN      124

データフレームが用意できたらpx.barfigを作成する。px.barで主に使われる引数は以下。

  • data_frame: データ元のpandasデータフレーム
  • x: 横軸にする、データフレームの列名
  • y: 縦軸にする、データフレームの列名

x, yについては配列から作成する方法で解説したが、data_frameを使うと意味合いが変わる。data_frameを使用するとx, yはデータフレームの列名を指定することができる。

上のグラフだと横軸がyearで縦軸はpopになるように、data_canadaの列yearpopを指定する。もちろん’year’とせずにdata_canada[’year’]pandasのシリーズで指定してもいいけど、同じグラフができるので単に’year’にする方が楽。

fig = px.bar(data_frame=data_canada, x='year', y='pop')
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフの保存
prefix = 'plotly-px-bar'
save_name = f"{prefix}_data_canada"
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")

データフレームを全ての国にすると何が何やら

なお、棒グラフにカナダのデータを使ったのは公式がそうしているからってのもあるけど、全ての国にしてしまうと何が何やらわからなくなるってのも理由の1つ。

上のグラフはシンプルに使用するデータをdata_canadaからdfにしただけだが、全ての国の人口が同じ色で区別されてしまう。色分けをしたらなんとかなる。後述。

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

df = px.data.gapminder()

fig = px.bar(data_frame=df, x='year', y='pop')
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフの保存
prefix = 'plotly-px-bar'
save_name = f"{prefix}_all_countries"
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")

px.barは自動積み上げ

pxの棒グラフpx.barでは各データは自動的に上に積み上がる。

縦長のデータフレームはシンプルに作成可能


px.barは自動的に積み上げ式の棒グラフを作成してくれる。なお、go.Barはデフォルトで棒グラフが横並びになる。これは好みだろうけど、個人的にはデフォルトが横並びの方がありがたい。

使用したデータフレームpxの金・銀・銅メダルの獲得国っぽいデータ。で、longって名のつくデータフレームの場合は以下のように列名がnation, medal, countの3データ。

この場合は先ほどと同様にx, yを指定するだけで棒グラフができる。また、ここではpx.barの引数colorで棒グラフごとに色付けし、引数titleでグラフタイトルを追加した。

引数colorはデータフレームの列名を指定することで、その列名で自動的に色分けしてくれる。

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

# 縦にgold, silver, bronzeが並んだデータフレーム
long_df = px.data.medals_long()
print(long_df)
#         nation   medal  count
# 0  South Korea    gold     24
# 1        China    gold     10
# 2       Canada    gold      9
# 3  South Korea  silver     13
# 4        China  silver     15
# 5       Canada  silver     12
# 6  South Korea  bronze     11
# 7        China  bronze      8
# 8       Canada  bronze     12

# colorを指定することで、データごとに色分けされる
# 積み上げは自動で行われる
fig = px.bar(
    long_df, x='nation', y='count',
    color='medal',  # metal列のデータで色分け
    title='Long-Form Input',  # グラフタイトルを追加
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフの保存
prefix = 'plotly-px-bar'
save_name = f"{prefix}_long_df"
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")

横長のデータフレームだと指定が必要


今度はwideと名のつくデータフレームを使用。こちらはデータフレームのデータの基準が国と金・銀・銅となっている。この場合は縦軸yを配列形式を使ってどのデータを使用するか指定しないといけない。

これでlongの時と同じグラフができるかといえばそうではなくて、凡例のmedal表記がなくなって代わりに自動的にvariableが表記される。

もし、凡例にタイトルが欲しかったら、fig.update_layout(legend_title_text='medal')などとして凡例タイトルを手動でつけないといけない。

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

# 横にgold, silver, bronzeが並んだデータフレーム
wide_df = px.data.medals_wide()
print(wide_df)
#         nation  gold  silver  bronze
# 0  South Korea    24      13      11
# 1        China    10      15       8
# 2       Canada     9      12      12

# 複数列をyとして扱う
# この時は凡例のタイトルがvariableになる
fig = px.bar(
    wide_df, x='nation', y=['gold', 'silver', 'bronze'],
    title='Wide-Form Input',
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフの保存
prefix = 'plotly-px-bar'
save_name = f"{prefix}_wide_df"
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")

棒グラフを色分け

複数データを同時に棒グラフにしたいときは色分けが必須。ここでは色分けについて解説する。

単に色分け指定しただけだとわかりづらいだけ

色分けはすでにmedalのところでも指定したが、引数colorで実行可能。ここでは最初のギャップマインダーのデータの国名で色分けするべく、color='country'としたんだけど、色んな色が入り混じって見づらい。

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

df = px.data.gapminder()
print(df)
#           country continent  year  ...   gdpPercap  iso_alpha  iso_num
# 0     Afghanistan      Asia  1952  ...  779.445314        AFG        4
# 1     Afghanistan      Asia  1957  ...  820.853030        AFG        4
# 2     Afghanistan      Asia  1962  ...  853.100710        AFG        4
# 3     Afghanistan      Asia  1967  ...  836.197138        AFG        4
# 4     Afghanistan      Asia  1972  ...  739.981106        AFG        4
# ...           ...       ...   ...  ...         ...        ...      ...
# 1699     Zimbabwe    Africa  1987  ...  706.157306        ZWE      716
# 1700     Zimbabwe    Africa  1992  ...  693.420786        ZWE      716
# 1701     Zimbabwe    Africa  1997  ...  792.449960        ZWE      716
# 1702     Zimbabwe    Africa  2002  ...  672.038623        ZWE      716
# 1703     Zimbabwe    Africa  2007  ...  469.709298        ZWE      716

# [1704 rows x 8 columns]

# シンプルに色分けする列だけ指定しても見づらいだけ
fig = px.bar(df, x='year', y='pop', color='country')
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフの保存
prefix = 'plotly-px-bar'
save_name = f"{prefix}_country_color"
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")

カラーマップで色分けする


国ごとにキレイに色を変更したいんだけ、如何せん国の数が多い。country列のデータを一意にして抽出すると以下。

import matplotlib.cm as cm
import plotly
import plotly.express as px
import plotly.io as pio

df = px.data.gapminder()
# 国一覧
countries = df['country'].unique()
print(countries)
# ['Afghanistan' 'Albania' 'Algeria' 'Angola' 'Argentina' 'Australia'
#  'Austria' 'Bahrain' 'Bangladesh' 'Belgium' 'Benin' 'Bolivia'
#  'Bosnia and Herzegovina' 'Botswana' 'Brazil' 'Bulgaria' 'Burkina Faso'
#  'Burundi' 'Cambodia' 'Cameroon' 'Canada' 'Central African Republic'
#  'Chad' 'Chile' 'China' 'Colombia' 'Comoros' 'Congo, Dem. Rep.'
#  'Congo, Rep.' 'Costa Rica' "Cote d'Ivoire" 'Croatia' 'Cuba'
#  'Czech Republic' 'Denmark' 'Djibouti' 'Dominican Republic' 'Ecuador'
#  'Egypt' 'El Salvador' 'Equatorial Guinea' 'Eritrea' 'Ethiopia' 'Finland'
#  'France' 'Gabon' 'Gambia' 'Germany' 'Ghana' 'Greece' 'Guatemala' 'Guinea'
#  'Guinea-Bissau' 'Haiti' 'Honduras' 'Hong Kong, China' 'Hungary' 'Iceland'
#  'India' 'Indonesia' 'Iran' 'Iraq' 'Ireland' 'Israel' 'Italy' 'Jamaica'
#  'Japan' 'Jordan' 'Kenya' 'Korea, Dem. Rep.' 'Korea, Rep.' 'Kuwait'
#  'Lebanon' 'Lesotho' 'Liberia' 'Libya' 'Madagascar' 'Malawi' 'Malaysia'
#  'Mali' 'Mauritania' 'Mauritius' 'Mexico' 'Mongolia' 'Montenegro'
#  'Morocco' 'Mozambique' 'Myanmar' 'Namibia' 'Nepal' 'Netherlands'
#  'New Zealand' 'Nicaragua' 'Niger' 'Nigeria' 'Norway' 'Oman' 'Pakistan'
#  'Panama' 'Paraguay' 'Peru' 'Philippines' 'Poland' 'Portugal'
#  'Puerto Rico' 'Reunion' 'Romania' 'Rwanda' 'Sao Tome and Principe'
#  'Saudi Arabia' 'Senegal' 'Serbia' 'Sierra Leone' 'Singapore'
#  'Slovak Republic' 'Slovenia' 'Somalia' 'South Africa' 'Spain' 'Sri Lanka'
#  'Sudan' 'Swaziland' 'Sweden' 'Switzerland' 'Syria' 'Taiwan' 'Tanzania'
#  'Thailand' 'Togo' 'Trinidad and Tobago' 'Tunisia' 'Turkey' 'Uganda'
#  'United Kingdom' 'United States' 'Uruguay' 'Venezuela' 'Vietnam'
#  'West Bank and Gaza' 'Yemen, Rep.' 'Zambia' 'Zimbabwe']

多くのデータを一括で色決めしたい時はカラーマップを使用するのが楽。なんだけど、plotlyでは予め色が決められていて使いづらい。これについてはあとで解説する

ここでは、色の数を自由に決められるmatplotlibのカラーマップを使用してグラフをキレイにする。

下のコードでは全ての国(アルファベット順)が何番目にあるかでカラーマップを作成。例えばAfghanistanならnum=0の0番目になる。

# 最終的に国ごとに'rgb(0, 0, 128)'の形式で色を作成
# 数が多いので、色が多少ダブる
colors = []
for num, _ in enumerate(countries):
    cmap = cm.jet(num / len(countries))
    rgb = plotly.colors.convert_to_RGB_255(cmap)
    color = f"rgb{rgb}"
    colors.append(color)

これで計算されるcmapの値はRed, Green, Blueそれぞれが0-1の間の値。対してplotlyでは0-255を使用するのでその補正をplotly.colors.convert_to_RGB_255で行っている。

また、単に(R, G, B)の配列じゃダメで、rgb(R, G, B)としないといけないので先頭にrgbという文字列をつけている。

colors一覧は以下。小数点以下が切り捨てられ整数値として出力されるので、値がダブっているものもあるけどここでは気にしないことにする。

これで色の配列ができたので、あとは引数color_discrete_sequenceに入れてあげると、国ごとに配列の色が適用される。

もちろん今回のようにカラーマップを使用せず、['red'., 'blue', 'green']のようにCSSカラーで色を指定して反映させてもいい。

# plotlyのJetの色の数より国名の方が多いので、自作の色にする必要がある
# plotlyのJetにするとJetの色の組み合わせが繰り返される
fig = px.bar(
    df, x='year', y='pop',
    color='country',
    color_discrete_sequence=colors,
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフの保存
prefix = 'plotly-px-bar'
save_name = f"{prefix}_country_color_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")

plotlyのカラーマップだと色が少ない

いちいちmatplotlibで色を作成するのが面倒って意見はあると思うけど、plotlyのカラーマップだと色が極端に少ない。

例えばplotlyjetであるpx.colors.sequential.Jetだと全部で6色しかない。

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

print(px.colors.sequential.Jet)
# ['rgb(0,0,131)', 'rgb(0,60,170)', 'rgb(5,255,255)', 'rgb(255,255,0)', 'rgb(250,0,0)', 'rgb(128,0,0)']

一方で、matplotlibの場合だと上で書いたように、全体の配列の中の何番目に該当するかで色を作成するので、決まった数がない。ここが自由度の分かれ目。

plotlyのカラーマップでは、色の数がデータよりも少ない場合は、色が繰り返し使用される。なので上の棒グラフのようにちょっとグロテスクな感じになってしまう。

fig = px.bar(
    df, x='year', y='pop',
    color='country',
    color_discrete_sequence=px.colors.sequential.Jet,  # 色が繰り返される
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフの保存
prefix = 'plotly-px-bar'
save_name = f"{prefix}_country_color_jet_plotly"
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")

数値で色分けなら簡単

さっきは国ごとに色分けをして苦戦したんだけど、数値データを色分けするのなら話が変わる。ここではギャップマインダーのカナダのデータから平均寿命で色分けした。

数値データを色分けするだけだからわざわざ色んな色を用意する必要がない。最大値と最小値が分かればそれでいい。

なお、以下のコードではホバーに表示する内容を変更する引数hover_dataや、表示する内容を変更するlabelsを使用している。

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

df = px.data.gapminder()
data_canada = df.query("country == 'Canada'")

print(data_canada)
#     country continent  year  lifeExp       pop    gdpPercap iso_alpha  iso_num
# 240  Canada  Americas  1952   68.750  14785584  11367.16112       CAN      124
# 241  Canada  Americas  1957   69.960  17010154  12489.95006       CAN      124
# 242  Canada  Americas  1962   71.300  18985849  13462.48555       CAN      124
# 243  Canada  Americas  1967   72.130  20819767  16076.58803       CAN      124
# 244  Canada  Americas  1972   72.880  22284500  18970.57086       CAN      124
# 245  Canada  Americas  1977   74.210  23796400  22090.88306       CAN      124
# 246  Canada  Americas  1982   75.760  25201900  22898.79214       CAN      124
# 247  Canada  Americas  1987   76.860  26549700  26626.51503       CAN      124
# 248  Canada  Americas  1992   77.950  28523502  26342.88426       CAN      124
# 249  Canada  Americas  1997   78.610  30305843  28954.92589       CAN      124
# 250  Canada  Americas  2002   79.770  31902268  33328.96507       CAN      124
# 251  Canada  Americas  2007   80.653  33390141  36319.23501       CAN      124

# 数値データであるlifeExpで色分け
fig = px.bar(
    data_canada, x='year', y='pop',
    hover_data=['lifeExp', 'gdpPercap'],  # ホバーのx, y以外に表示する情報
    color='lifeExp',  # 平均寿命で色分け
    labels={'pop': 'population of Canada'},  # ホバーのpopの表記を変更
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフの保存
prefix = 'plotly-px-bar'
save_name = f"{prefix}_lifeExp"
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にカラースケール名を入れるだけ
fig = px.bar(
    data_canada, x='year', y='pop',
    hover_data=['lifeExp', 'gdpPercap'],
    color='lifeExp',
    labels={'pop': 'population of Canada'},
    color_continuous_scale='Jet',  # カラースケールを変更
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフの保存
prefix = 'plotly-px-bar'
save_name = f"{prefix}_lifeExp_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")

同じ横軸のデータが複数ある場合


横軸のデータに対して縦軸のデータが複数ある場合は自動的に積み上げて区別が多少つきやすいように白っぽい線をつけてくれる。

今回はMaleとFemaleを横軸としたけど、そうするとこれら2つでデータが自動的に分けられる。なお、color'time'に指定することで、Maleの中でtimeを自動で色分けしてくれる。

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

df_tips = px.data.tips()
print(df_tips)
#      total_bill   tip     sex smoker   day    time  size
# 0         16.99  1.01  Female     No   Sun  Dinner     2
# 1         10.34  1.66    Male     No   Sun  Dinner     3
# 2         21.01  3.50    Male     No   Sun  Dinner     3
# 3         23.68  3.31    Male     No   Sun  Dinner     2
# 4         24.59  3.61  Female     No   Sun  Dinner     4
# ..          ...   ...     ...    ...   ...     ...   ...
# 239       29.03  5.92    Male     No   Sat  Dinner     3
# 240       27.18  2.00  Female    Yes   Sat  Dinner     2
# 241       22.67  2.00    Male    Yes   Sat  Dinner     2
# 242       17.82  1.75    Male     No   Sat  Dinner     2
# 243       18.78  3.00  Female     No  Thur  Dinner     2

# [244 rows x 7 columns]

# 同じ横軸の場合はが複数ある場合の自動的に積み上げされる
fig = px.bar(
    df_tips, x='sex', y='total_bill', color='time'
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフの保存
prefix = 'plotly-px-bar'
save_name = f"{prefix}_tips_time"
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")

barmodeで積み上げずに並べる

引数barmode='group'に指定することで、棒グラフを積み上げではなく横に並べることが可能。ここではtimeで色分けしたのでそれに沿って横に並べられている。

なお、barmodeのデフォルトはrelativeでこれは正の数は上方向に、負の数は下方向に棒グラフが作成されるようになる。このグラフはマイナスがないから実現できない。

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

# 積み上げをやめて並べたかったら引数barmode='group'にする
fig = px.bar(
    df_tips, x='sex', y='total_bill',
    color='time',
    barmode='group',  # 積み上げをやめて横に並べる
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフの保存
prefix = 'plotly-px-bar'
save_name = f"{prefix}_tips_time_group"
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")

# relativeにすると正の値+、負の値は−方向にbarが伸びる

棒グラフに模様をつける

ここまで棒グラフには色をつけてデータの判断をしていたが、色に加えてパターン(模様)をつけることも可能。

引数pattern_shapeでどの列名を基準に模様をつけるのかを指定可能。ここではlong_dfに対してnation列を指定した。

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

long_df = px.data.medals_long()
print(long_df)
#         nation   medal  count
# 0  South Korea    gold     24
# 1        China    gold     10
# 2       Canada    gold      9
# 3  South Korea  silver     13
# 4        China  silver     15
# 5       Canada  silver     12
# 6  South Korea  bronze     11
# 7        China  bronze      8
# 8       Canada  bronze     12

fig = px.bar(
    long_df, x='medal', y='count',
    color='nation',
    pattern_shape='nation',  # パターンを適用する列名
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフの保存
prefix = 'plotly-px-bar'
save_name = f"{prefix}_patterns"
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")

自分でパターンを決める

パターンについては自分で指定することも可能。どのパターンが使用できるかは公式の「Patterns, Hatching, Texture in Python」や以下の記事を参照。ここでは., x, +を使用。

【plotly&pattern】棒グラフとかのパターンまとめ

こんな人にオススメ plotlyの棒| ...

続きを見る

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

long_df = px.data.medals_long()
print(long_df)
#         nation   medal  count
# 0  South Korea    gold     24
# 1        China    gold     10
# 2       Canada    gold      9
# 3  South Korea  silver     13
# 4        China  silver     15
# 5       Canada  silver     12
# 6  South Korea  bronze     11
# 7        China  bronze      8
# 8       Canada  bronze     12

fig = px.bar(
    long_df, x='medal', y='count',
    color='nation',
    pattern_shape='nation',
    pattern_shape_sequence=['.', 'x', '+'],  # パターンの種類
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフの保存
prefix = 'plotly-px-bar'
save_name = f"{prefix}_patterns_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")

facet_colでサブプロットっぽくする


最後は引数facet_colを使ってサブプロットっぽくする方法。facet_colについては以下の記事で詳しく解説している。

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

こんな人にオススメ plotly.express、px ...

続きを見る

ここでは行をfacet_row='time'に、列をfacet_col='day'に設定して、行と列の2軸でサブプロットっぽくデータを扱っている。

また、引数category_ordersでデータの順番を指定することで、曜日がバラバラになるのを防いでいる。

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

df_tips = px.data.tips()
print(df_tips)
#      total_bill   tip     sex smoker   day    time  size
# 0         16.99  1.01  Female     No   Sun  Dinner     2
# 1         10.34  1.66    Male     No   Sun  Dinner     3
# 2         21.01  3.50    Male     No   Sun  Dinner     3
# 3         23.68  3.31    Male     No   Sun  Dinner     2
# 4         24.59  3.61  Female     No   Sun  Dinner     4
# ..          ...   ...     ...    ...   ...     ...   ...
# 239       29.03  5.92    Male     No   Sat  Dinner     3
# 240       27.18  2.00  Female    Yes   Sat  Dinner     2
# 241       22.67  2.00    Male    Yes   Sat  Dinner     2
# 242       17.82  1.75    Male     No   Sat  Dinner     2
# 243       18.78  3.00  Female     No  Thur  Dinner     2

# [244 rows x 7 columns]

fig = px.bar(
    df_tips, x='sex', y='total_bill',
    color='smoker', barmode='group',
    facet_row='time',  # 縦軸の分け方は時間帯
    facet_col='day',  # 横軸の分け方は曜日
    # category_ordersでプロットする順番を決める
    category_orders={
        'day': ['Thur', 'Fri', 'Sat', 'Sun'],  # 曜日がバラバラになるので指定
        'time': ['Lunch', 'Dinner']  # ランチとディナーの順番が逆になるので指定
    }
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(font_size=20, hoverlabel_font_size=20)
fig.show()

# グラフの保存
prefix = 'plotly-px-bar'
save_name = f"{prefix}_facet"
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でサブプロットっぽいグラフを作成した。

今回は引数face_colで国名を指定し、引数facet_col_wrapで列の数を指定。20ヵ国分のデータがあったので列数は5として4 x 5のグラフに。

また、国によって人口の差が激しいので縦軸はlog_y=Trueで対数表示にしている。レイアウトは、グラフの高さ、凡例の向きを変更している。

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

# ギャップマインダーのデータ
df = px.data.gapminder()

# アメリカ大陸のデータだけ抽出
df_Americas = df[df['continent'] == 'Americas']
print(df_Americas)
#         country continent  year  ...     gdpPercap  iso_alpha  iso_num
# 48    Argentina  Americas  1952  ...   5911.315053        ARG       32
# 49    Argentina  Americas  1957  ...   6856.856212        ARG       32
# 50    Argentina  Americas  1962  ...   7133.166023        ARG       32
# 51    Argentina  Americas  1967  ...   8052.953021        ARG       32
# 52    Argentina  Americas  1972  ...   9443.038526        ARG       32
# ...         ...       ...   ...  ...           ...        ...      ...
# 1639  Venezuela  Americas  1987  ...   9883.584648        VEN      862
# 1640  Venezuela  Americas  1992  ...  10733.926310        VEN      862
# 1641  Venezuela  Americas  1997  ...  10165.495180        VEN      862
# 1642  Venezuela  Americas  2002  ...   8605.047831        VEN      862
# 1643  Venezuela  Americas  2007  ...  11415.805690        VEN      862

# [300 rows x 8 columns]

fig = px.bar(
    df_Americas, x='year', y='pop',
    color='country',
    facet_col='country', facet_col_wrap=5,  # 国ごとに5列になるように分ける
    log_y=True,  # 縦軸をlog(常用対数)表示
)
# グラフ全体とホバーのフォントサイズ変更
fig.update_layout(
    height=1000,  # グラフの高さ
    hoverlabel_font_size=20,
    legend_orientation='h'  # 凡例の向き
)
fig.show()

# グラフの保存
prefix = 'plotly-px-bar'
save_name = f"{prefix}_df_Americas"
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.barを使って棒グラフを作成する方法を解説した。棒グラフは折れ線グラフとか散布図とかに次いでメジャーなグラフの1つ。

なのでその分使う頻度が多いだろう。それもあってか機能が少なめなpxでもそれなりに色んなグラフを作成することが可能。

今回の記事をきっかけに自分なりに色々とカスタムしてより見やすいグラフにしていただけると幸いだ。

関連記事


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

こんな人にオススメ pxで塗り& ...

続きを見る


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

こんな人にオススメ plotlyの中{ ...

続きを見る


【plotly&scatter_matrix】複数種の軸を持つsubplotをpxで描画

こんな人にオススメ pxにscatter_matrix ...

続きを見る


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

こんな人にオススメ plotlyのpxで3D& ...

続きを見る


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

こんな人にオススメ plotly.express、px ...

続きを見る


【px&バブルチャート】plotly.expressで各国の収入と平均寿命の時代変化をアニメーションで

こんな人にオススメ 今は世 ...

続きを見る


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

こんな人にオススメ plotlyでア| ...

続きを見る

 

スイッチボット

2022/11/28

【SwitchBotロックレビュー】これからのスタンダードになりうるスマートロック

こんな人にオススメ SwitchBotからスマートロック「SwitchBotロック」が発売された ...

生活に役立つ

2022/11/28

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

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

マウス

2022/9/11

【Logicool MX ERGO vs MX Master 3】ERGOをメインにした決定的な理由

こんな疑問・お悩みを持っている人におすすめ 執筆者はLogicoolのハイエンӠ ...

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

2022/11/21

【ながら聴きイヤホン比較】SONY LinkBuds、ambie、BoCoはどれがおすすめ?

こんな人におすすめ 耳を塞がない開放型のイヤホンに完全ワイヤレスӟ ...

macOSアプリケーション

2022/10/15

【M1 Mac】MacBook Proに入れている便利でニッチなアプリを21個紹介する

こんな人におすすめ MacBookを購入してLINEとか必要最低限のアプリは入れた。 ...

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

2022/10/23

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

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

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

2022/11/21

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

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

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

2022/8/19

【Nothing ear (1)レビュー】ライトな完成度、アップデートに期待

こんな人にオススメ 完全ワイヤレスイヤホン(TWS)でスケルトンボディ ...

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

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

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

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

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

  • この記事を書いた人

メガネ

ベンチャー企業のWebエンジニア駆け出し。独学のPythonで天文学系の大学院を修了→新卒を1.5年で辞める→転職→今に至る。
常時金欠のガジェット好きでM1 MacBook Pro x Galaxy S22 Ultraの狂人。
人見知りで根暗だったけど、人生楽しもうと思って良い方向に狂う→人生が楽しい

ガジェットのレビューとPythonコードを記事にしています。ぜひ楽しんでください🦊
自己紹介と半生→変わって楽しいの繰り返し

-px
-, , , ,