-
まずは、Pythonの開発環境を準備する
まずは、
「記事(Article137)」を参照して、
Pythonの開発環境を準備してください。
ここでは、Pythonのプロジェクトフォルダとして「Plotly」を使用しています。
図1は、Visual Studio Code(VS Code)の「Terminal」メニューから「New Terminal」を選択して、
「Terminal」ウィンドウを開いたときの画面です。
緑色の「(venv)」が表示されていれば、 Pythonの仮想環境が正常に作成されていることになります。
-
Visual Studio Codeを起動してプログラムファイルを作成する
Pythonの開発環境の準備が完了したら、 VS Codeを起動して新規のPythonファイル(*.py)を作成します。
ここで作成したPythonのファイルには「リスト13-1」のコードをコピペします。
図2は、VS Codeの画面です。
-
まずは、Plotly Expressでシンプルな円グラフを作成して見る
ここでは、中国、インド、インドネシア、日本の人口の円グラフを作成します。
Plotly Expressで円グラフを作成するには「pie()」メソッドを使用します。
引数「names」には国名リストの変数名「country」、引数「values」には人口リストの変数名「population」を指定しています。
これで人口の円グラフが作成されます。国別のパーセント(%)は自動的に表示されます。
ここでは、さらに円グラフにタイトル、テーマなどを追加していきます。
以下、解説は図の説明で行います。
### import the libraries
import numpy as np
import pandas as pd
import plotly.io as pio
import plotly.express as px
import plotly.graph_objects as go
'''
plotly.express.pie(
data_frame=None,
names=None, values=None,
color=None,
facet_row=None, facet_col=None,
facet_col_wrap=0, facet_row_spacing=None, facet_col_spacing=None,
color_discrete_sequence=None, color_discrete_map=None,
hover_name=None, hover_data=None,
custom_data=None,
category_orders=None,
labels=None,
title=None,
template=None,
width=None, height=None,
opacity=None, hole=None)
→ plotly.graph_objects._figure.Figure
'''
# simple pie chart
country = ['China', 'India', 'Indonesia', 'Japan']
population = [1280400000, 1034172547, 211060000, 127065841]
fig = px.pie(names=country, values=population)
fig.show()
# %%
# add a title
fig = px.pie(names=country, values=population,
title='px pie(names=country, values=population, title=...)'
)
fig.show()
# %%
# add a template (theme)
fig = px.pie(names=country, values=population,
template='plotly_dark',
title='px pie(names=, values=, template=plotly_dark)'
)
fig.show()
# set a default template
pio.templates.default = 'plotly_dark'
# pio.templates.default = 'plotly_white'
fig = px.pie(names=country, values=population,
title='px pie(...): pio.templates.default=plotly_dark'
)
fig.show()
# %%
図3-1には、シンプルな4カ国の人口の円グラフが表示されています。
円グラフのパーセント(%)は、自動的に表示されます。
円グラフにマウスをホバリングさせると、ホバーテキスト「国名、人口」が表示されます。
このように、Plotlyではデフォルトの状態でインタラクティブ機能が有効になっています。
図3-2では、凡例から国名「Indonesia」をクリックして円グラフを削除しています。
円グラフから削除されると凡例がグレーアウトされます。
再度「Indonesia」をクリックすると円グラフに追加されます。
図3-3では、Plotly Expressの「pie()」メソッドに引数「title」を追加して円グラフのタイトルを表示しています。
図3-4では、Plotly Expressの「pie()」メソッドに引数「template」を追加して円グラフのテーマを設定しています。
ここではダークモードの「plotly_dark」を設定しています。
図3-5では、Plotly Expressの「pie()」メソッドではなく、
pioクラスの「templates.default」にテーマ「plotly_dark」を設定しています。
この場合、Plotly Expressの全てのグラフがダークモードで表示されるようになります。
「templates.default」の初期値は「plotly_white」になっています。
-
Plotly ExpressのgapminderデータをPandasのDataFrameに取り込む
ここでは、Plotly Expressが用意している「gapminder」データをPandasのDataFrameに取り込んで後述するステップで利用します。
# load data from plotly express gapminder()
raw_df = px.data.gapminder()
# raw_df.info()
# raw_df
# raw_df['continent'].unique()
df = raw_df.query("continent=='Asia'")
# df['country'].unique()
# len(df['country'].unique().tolist())
図4-1では、「px.data.gapminder()」メソッドで世界の人口データ等をPandasのDataFrameに取り込んでいます。
DataFrameは「country, continent, year, lifeExp, pop, gdpPercap,...」などのカラムから構成されています。
「country」には「国名」、
「continent」には「大陸名」、「year」には「年度」、「lifeExp」には「平均寿命」、「pop」には「人口」、
「gdpPercap」には「一人当たりの国内総生産]が格納されています。
図4-2では、アジアの国名と件数を表示しています。
DataFrameには33カ国のアジアの国名が登録されています。
-
PandasのDataFrameから「アジア」の国々を絞り込んで人口の上位6位までを円グラフに表示する
ここでは、アジアの人口上位6位までの国とその他を円グラフにします。
7位以下の国は「Other countries(その他)」として表示します。
DataFrameから「アジア」の「2002」年のデータを絞り込むのに「query()」メソッドを使用しています。
人口が上位6位までの国を絞り込むには「nlargest()」メソッドを使用します。
7位以下の国々を「その他」としてまとめるには、
DataFrameのカラム「country(国名)」を「other countries」に書き換えます。
そして、DataFrameの「groupby().agg(sum)」メソッドで人口を再計算します。
# pie chart : Asia top 6 + others
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(6, 'pop')
pop_min = df['pop'].min()
# pop_min
df = raw_df.query("continent=='Asia'") \
.query("year==2002")
df.loc[df['pop'] < pop_min, 'country'] = 'Other countries' # Represent only large countries
df = df.groupby('country').agg(sum)
df.reset_index(inplace=True)
# df
fig = px.pie(df, names='country', values='pop',
color='country',
title='px pie(names=country, values=pop): asia top 6 + others'
)
fig.show()
# pie chart : Asia top 6 + others + pull(go)
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(6, 'pop')
pop_min = df['pop'].min()
df = raw_df.query("continent=='Asia'") \
.query("year==2002")
df.loc[df['pop'] < pop_min, 'country'] = 'Other countries' # Represent only large countries
df = df.groupby('country').agg(
{'pop': 'sum', 'year': 'last'}
)
df.reset_index(inplace=True)
fig = go.Figure(
data=[
go.Pie(
labels=df['country'],
values=df['pop'],
pull=[0, 0, 0, 0, 0, 0.3, 0]
)
])
fig.update_layout(title='go pie(labels=country, values=pop, pull=[...])')
fig.show()
図5-1では、変数「pop_min」の内容と、PandasのDataFrame(df)の内容を表示してします。
「pop_min」には6位の人口が格納されています。
DataFrameには、上位6位までのデータと「その他」のデータが格納されています。
図5-2には、DataFrameの内容が円グラフで表示されています。
円グラフには人口の上位6位までの国とその他の国が表示されています。
1位が中国、2位がインド、3位はその他になっています。
ちなみに、日本はその他を含めて7位になっています。
図5-3では、円グラフから「Other countries(その他)」を分離させています。
円グラフから特定の要素を分離させるには、Plotly Graph Objects(go)の「pull=」を使用します。
図5-1のDataFrameの内容から「Other countries」は先頭から6番目になっています。
なので、引数「pull=」に指定するリスト型データの6番目に「0.3」を設定します。
この数値を調整することで分離させる位置を調整することができます。
-
Plotly Expressの「pie()」メソッドに引数「hover_data, labels」を追加してホバーテキストをカスタマイズする
Plotlyは、マウスを円グラフにホバリングさせるとホバーテキストを表示します。
デフォルトでは「names, values」の値が表示されます。
たとえば、円グラフにマウスを移動すると「国名」と「人口」が表示されます。
ここでは、ホバーテキストに「life expectancy(平均寿命)」を追加しています。
ホバーテキストにデータを追加するには「pie()」メソッドの引数に「hover_data=」を追加します。
ホバーテキストにDataFrameのカラム名「lifeExp」ではなく「life expectancy」を
表示させるには「labels=」を追加します。
# pie chart : add a hovoer_data=, labels=
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(6, 'pop')
pop_min = df['pop'].min()
df = raw_df.query("continent=='Asia'") \
.query("year==2002")
df.loc[df['pop'] < pop_min, 'country'] = 'Other countries'
df = df.groupby('country').agg(sum)
df.reset_index(inplace=True)
fig = px.pie(df, names='country', values='pop',
hover_data=['lifeExp'], labels=dict(lifeExp='life expectancy'),
title='px pie(..., hover_data=, labels=) '
)
fig.show()
図6では、ホバーテキストに「country(国名), pop(人口), life expectancy(平均寿命)」が表示されています。
-
Plotly Expressの「pie()」メソッドに引数「hover_data」を追加してホバーテキストに人口の「ランク」を表示する
ここでは、円グラフのホバーテキストに「rank(人口のランク)」を追加しています。
ホバーテキストにデータを追加するには「pie()」メソッドの引数に「hover_data=」を追加します。
# pie chart : Asia top 8 + hover_data=rank
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(8, 'pop')
df.reset_index(inplace=True)
df['rank'] = df.index+1
fig = px.pie(df, names='country', values='pop',
hover_data=['rank'],
title='px pie(...): asia top 8 + hover_data=rank'
)
fig.show()
図7では、ホバーテキストに「country(国名)、pop(人口)、rank(ランク)」が表示されています。
-
Plotly Expressのpie()メソッドに引数「hole=0.3」を追加してドーナツ型の円グラフにする
ここでは、ドーナツ型の円グラフを表示します。
円グラフをドーナツ型にするには、「pie()」メソッドの引数に「hole=」を追加します。
# pie chart : Asia top 8 + hole=0.3
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(8, 'pop')
fig = px.pie(df, names='country', values='pop',
color='country',
hole=0.3,
title='px pie(...): asia top 8 + hole=0.3'
)
fig.show()
図8には、ドーナツ型の円グラフが表示されています。
-
Figure「update_layput()」メソッドに引数「annotations」を追加してドーナツ型円グラフの中央に「Asia top 8」を表示する
ここでは、ドーナツ型の円グラフの中央に「Asia top 8」を表示しています。
円グラフに「注釈」を追加するには、
「update_layout()」メソッドに引数「annotations=」を追加します。
annotationsの引数には「text=, x=, y=,...」でテキスト文字、表示位置などを指定します。
# pie chart : Asia top 8 + hole=0.4 + annotations
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(8, 'pop')
fig = px.pie(df, names='country', values='pop',
color='country',
hole=0.4,
title='px pie(...): asia top 8 + hole=0.1 + annotations=...'
)
fig.update_layout(
# Add annotations in the center of the donut pie.
annotations=[dict(text='Asia top 8', x=0.50, y=0.5, font_size=20, showarrow=False)]
)
fig.show()
図9では、ドーナツ型円グラフの中央に「Asia top 8」が表示されています。
-
Figureの「update_traces()」メソッドに引数「textinfo」を追加して円グラフに「国名、%」を表示する
ここでは、円グラフに「国名、人口のパーセント」を表示させています。
円グラフに「国名、%」を追加するには、
「update_traces()」メッソドの引数に「textposition=, textinfo=」を追加します。
# pie chart : Asia top 6 + textinfo + hover_data
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(6, 'pop')
df.reset_index(inplace=True)
df['rank'] = df.index+1
fig = px.pie(df, names='country', values='pop',
hover_data=['rank'],
title='px pie(...): asia top 6 + textinfo=...'
)
fig.update_traces(textposition='inside', textinfo='percent+label')
fig.show()
図10では、円グラフに「国名、%」が表示されています。
-
Figureの「update_traces()」メソッドの引数に「texttemplate」を追加して円グラフに「国名、ランク」を表示する
ここでは、円グラフに「国名、ランク」を表示させています。
さらに、ホバーテキストには「国名、ランク、人口」を表示させています。
「pie()」メソッドの引数「names=, values=」以外のデータを表示させるには、
「custom_data=」を追加してDataFrameのカラム名「rank」を指定する必要があります。
ここでは、円グラフの「国名、ランク」を表示させるのに、
「update_traces()」メソッドに引数「textposition=, texttemplate=」を追加しています。
ホバーテキストに「国名、ランク、人口」を表示させるには、
「update_traces()」メソッドに引数「hovertemplate=」を追加します。
# pie chart : Asia top 6 + custome_data + texttemplate + hovertemplate
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(6, 'pop')
df.reset_index(inplace=True)
df['rank'] = df.index+1
fig = px.pie(df, names='country', values='pop',
custom_data=['rank'],
title='px pie(...): asia top 8 + textinfo=...'
)
fig.update_traces(
textposition='inside',
texttemplate="%{label}<br>Rank: %{customdata}",
hovertemplate="Country:%{label}<br>Rank: %{customdata}<br>Population: %{value}"
)
fig.show()
図11-1では、円グラフに「国名、ランク」が表示されています。
図11-2では、ホバーテキストに「国名、ランク、人口」が表示されています。
-
Plotly Graph Objectsの「Pie()」メソッドに引数「pull」を追加して円グラフから「日本」を切り離して強調する
ここでは、既に紹介したPlotly Graph Objects(go)の「pull」を使用して円グラフから「日本」を切り離しています。
# pie chart : Asia top 6 + pull(go)
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(6, 'pop')
fig = go.Figure(
data=[
go.Pie(
labels=df['country'],
values=df['pop'],
pull=[0, 0, 0, 0, 0, 0.3]
)
])
fig.update_layout(title='go pie(labels=country, values=pop, pull=[...])')
fig.show()
図12では、円グラフから「日本」が切り離されて強調されています。
DataFrameには日本のデータが先頭から6番目に格納されているので、
「pull=」の値にはリスト型の6番目の要素に「0.3」を指定します。
-
全てのコードを掲載
ここでは、本記事で解説している全てのコードを掲載しています。
リスト13-1: Article145.py
# Article145 Plotly Pie Chart v20.py
# %%
### import the libraries
import numpy as np
import pandas as pd
import plotly.io as pio
import plotly.express as px
import plotly.graph_objects as go
# %%
'''
plotly.express.pie(
data_frame=None,
names=None, values=None,
color=None,
facet_row=None, facet_col=None,
facet_col_wrap=0, facet_row_spacing=None, facet_col_spacing=None,
color_discrete_sequence=None, color_discrete_map=None,
hover_name=None, hover_data=None,
custom_data=None,
category_orders=None,
labels=None,
title=None,
template=None,
width=None, height=None,
opacity=None, hole=None)
→ plotly.graph_objects._figure.Figure
'''
# simple pie chart
country = ['China', 'India', 'Indonesia', 'Japan']
population = [1280400000, 1034172547, 211060000, 127065841]
fig = px.pie(names=country, values=population)
# hover(label=China, value=9999999)
fig.show()
# %%
# add a title
fig = px.pie(names=country, values=population,
title='px pie(names=country, values=population, title=...)'
)
fig.show()
# %%
# add a template (theme)
fig = px.pie(names=country, values=population,
template='plotly_dark',
title='px pie(names=, values=, template=plotly_dark)'
)
fig.show()
# %%
# set a defulat templte
pio.templates.default = 'plotly_dark'
# pio.templates.default = 'plotly_white'
fig = px.pie(names=country, values=population,
title='px pie(...): pio.templates.default=plotly_dark'
)
fig.show()
# %%
# load data from plotly express gapmider()
raw_df = px.data.gapminder()
# raw_df.info()
# raw_df
# raw_df['continent'].unique()
df = raw_df.query("continent=='Asia'")
# df['country'].unique()
# len(df['country'].unique().tolist())
# %%
fig = px.pie(df,
names='country', values='pop',
title='px pie(names=country, values=pop, title=...)'
)
fig.show()
# %%
# pie chart : Asia top 6 + others
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(6, 'pop')
pop_min = df['pop'].min()
# pop_min
df = raw_df.query("continent=='Asia'") \
.query("year==2002")
df.loc[df['pop'] < pop_min, 'country'] = 'Other countries' # Represent only large countries
df = df.groupby('country').agg(sum)
df.reset_index(inplace=True)
# df
fig = px.pie(df, names='country', values='pop',
color='country',
title='px pie(names=country, values=pop): asia top 6 + others'
)
fig.show()
# %%
# pie chart : Asia top 6 + others + pull(go)
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(6, 'pop')
pop_min = df['pop'].min()
df = raw_df.query("continent=='Asia'") \
.query("year==2002")
df.loc[df['pop'] < pop_min, 'country'] = 'Other countries' # Represent only large countries
df = df.groupby('country').agg(
{'pop': 'sum', 'year': 'last'}
)
df.reset_index(inplace=True)
fig = go.Figure(
data=[
go.Pie(
labels=df['country'],
values=df['pop'],
pull=[0, 0, 0, 0, 0, 0.3, 0]
)
])
fig.update_layout(title='go pie(labels=country, values=pop, pull=[...])')
fig.show()
# %%
# pie chart : add a hovoer_data=, labels=
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(6, 'pop')
pop_min = df['pop'].min()
# pop_min
df = raw_df.query("continent=='Asia'") \
.query("year==2002")
df.loc[df['pop'] < pop_min, 'country'] = 'Other countries' # Represent only large countries
df = df.groupby('country').agg(sum)
df.reset_index(inplace=True)
# df
fig = px.pie(df, names='country', values='pop',
hover_data=['lifeExp'], labels=dict(lifeExp='life expectancy'),
title='px pie(..., hover_data=, labels=) '
)
fig.show()
# %%
# pie chart : Asia top 8 + hover_data=rank
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(8, 'pop')
df.reset_index(inplace=True)
df['rank'] = df.index+1
fig = px.pie(df, names='country', values='pop',
hover_data=['rank'],
title='px pie(...): asia top 8 + hover_data=rank'
)
fig.show()
# %%
# pie chart : Asia top 8 + hole=0.3
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(8, 'pop')
fig = px.pie(df, names='country', values='pop',
color='country',
hole=0.3,
title='px pie(...): asia top 8 + hole=0.3'
)
fig.show()
# %%
# pie chart : Asia top 8 + hole=0.4 + annotations
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(8, 'pop')
fig = px.pie(df, names='country', values='pop',
color='country',
hole=0.4,
title='px pie(...): asia top 8 + hole=0.1 + annotations=...'
)
fig.update_layout(
# Add annotations in the center of the donut pie.
annotations=[dict(text='Asia top 8', x=0.50, y=0.5, font_size=20, showarrow=False)]
)
fig.show()
# %%
# pie chart : Asia top 6 + textinfo + hover_data
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(6, 'pop')
df.reset_index(inplace=True)
df['rank'] = df.index+1
fig = px.pie(df, names='country', values='pop',
hover_data=['rank'],
title='px pie(...): asia top 6 + textinfo=...'
)
fig.update_traces(textposition='inside', textinfo='percent+label')
fig.show()
# %%
# pie chart : Asia top 6 + custome_data + texttemplate + hovertemplate
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(6, 'pop')
df.reset_index(inplace=True)
df['rank'] = df.index+1
fig = px.pie(df, names='country', values='pop',
custom_data=['rank'],
title='px pie(...): asia top 8 + textinfo=...'
)
fig.update_traces(
textposition='inside',
texttemplate = "%{label}<br>Rank: %{customdata}",
hovertemplate = "Country:%{label}<br>Rank: %{customdata}<br>Population: %{value}"
)
fig.show()
# %%
# pie chart : Asia top 6 + pull(go)
df = raw_df.query("continent=='Asia'") \
.query("year==2002") \
.nlargest(6, 'pop')
fig = go.Figure(
data=[
go.Pie(
labels=df['country'],
values=df['pop'],
pull=[0, 0, 0, 0, 0, 0.3]
)
])
fig.update_layout(title='go pie(labels=country, values=pop, pull=[...])')
fig.show()