こんな人にオススメ
日本ってAppleのiPhoneが主流だけど、世界の場合はどうなるの?出荷台数とかシェアとか。
plotly
でここんところを可視化したい。
ということで、今回は世界のスマホ出荷台数などをplotly
の円グラフを使用して作成する。別にplotly
を使用しなくてもいいんだけど、使った方がキレイに作成できるし経験にもなるだろう。
円グラフのカスタムなどについては以下の記事参照。
-
-
【plotly&円グラフ】subplotsやボタンの適用
続きを見る
日本ではiPhoneが人気であるが、世界ではその様子が異なる。日本という閉鎖空間にいるだけではわからない外の世界の事情をみていこう。
python環境は以下。
- Python 3.9.6
- plotly 5.1.0
- plotly-orca 3.4.2
作成したコード全文
下準備
import sys import plotly.graph_objects as go import plotly.io as pio sys.path.append('../../') import plotly_layout_template as template
まずは下準備としてのimport
関連。今回はnumpy
などは使用せずdict
を使用してデータを整理する。plotly_layout_templateは自作のplotlyテンプレートで、これを使用することで簡単にキレイなグラフが作成可能。
-
-
【随時更新 備忘録】plotlyのグラフ即席作成コード
続きを見る
スマホの出荷台数のデータ
今回使用するデータは以下の3種類。
- 2021年の世界のスマホ出荷台数シェア(第一四半期: Q1と第二四半期Q2)
- 2021年の世界のスマホ出荷台数(Q1, Q2)
- 2020年の世界のスマホ出荷台数シェア(通年)
以下でこれらのデータの具体的な値を見ていく。
2021年の世界のスマホ出荷台数シェア
# 2021年の第一、第二四半期の市場シェア率 # 多分、小数点の関係で合計値が101%になっている # <https://www.canalys.com/newsroom/canalys-worldwide-smartphone-market-Q1-2021> # <https://canalys.com/newsroom/worldwide-smartphone-market-q2-2021> share2021 = { 'q1': { 'Samsung': 22, 'Apple': 15, 'Xiaomi': 14, 'Oppo': 11, 'Vivo': 10, 'Others': 28, }, 'q2': { 'Samsung': 18, 'Xiaomi': 17, 'Apple': 14, 'Oppo': 10, 'Vivo': 10, 'Others': 30, } }
世界のスマホシェアは1位がSamsung、2位がXiaomiもしくはAppleとなっている。ここ最近のXiaomiのものすごい勢いとApple自体の勢いの衰えでQ2では逆転された。Xiaomiすげ。
また、2021年からはHuaweiが一気に上位から陥落、これはアメリカからの制裁が原因で、これまで上位に位置していたのにここでは表示から消えた。これからどうなるのか。
2021年の世界のスマホ出荷台数
# スマホの出荷台数(100万台単位) # <https://www.canalys.com/newsroom/canalys-worldwide-smartphone-market-Q1-2021> # <https://canalys.com/newsroom/worldwide-smartphone-market-q2-2021> shipment2021 = { 'q1': { 'Samsung': 76.5, 'Apple': 52.4, 'Xiaomi': 49.0, 'Oppo': 37.6, 'Vivo': 36.0, 'Others': 95.9, }, 'q2': { 'Samsung': 58.0, 'Xiaomi': 52.8, 'Apple': 45.7, 'Oppo': 32.6, 'Vivo': 31.2, 'Others': 95.8, } }
スマホの出荷台数も傾向としては同じ感じで、Samsungが1位を守っている。また、XiaomiとAppleの関係もそのまま。こちらは単位が100万台なので、Q1のSamsungの場合は76.5*1,000,000=7650万台という計算になる。
SamsungのスマホはGalaxyだが、こちらはハイエンドのSシリーズやNoneシリーズだけではなく、低価格のAシリーズも展開されているところが大きなポイントとなっているだろう。
一方で、Xiaomiは低価格なのに高性能というコスパお化けなところが売れる原因だろう。
2020年通年のスマホ出荷台数シェア
# 2020年の世界のスマホ出荷台数シェア[%] # <https://www.counterpointresearch.com/apple-shipped-record-iphones-q4-2020-global-smartphone-market-continues-recover/> # 合計値は99(小数点とかでズレていると思われる) share2020 = { 'Samsung': 19, 'Apple': 15, 'Huawei': 14, 'Xiaomi': 11, 'Oppo': 8, 'Vivo': 8, 'Realme': 3, 'Lenovo group': 2, 'LG': 2, 'Tecno': 2, 'Others': 15, }
一方で、2020年の場合は様子が異なる。Huaweiが第3位にランクインしている。まだ制裁の傷が浅かったからだろうが、この上位への位置付けは2021年で終了することとなる。
このデータでは上位10ブランドが存在している。日本でRealmeが上陸するなどこれからのスマホ業界はどうなるのか楽しみだ。
各種ブランドのテーマカラー
color_dct = { 'Samsung': (3, 78, 162), 'Xiaomi': (255, 103, 0), 'Apple': (0, 0, 0), 'Oppo': (30, 163, 102), 'Vivo': (0, 114, 184), 'Huawei': (255, 0, 0), 'Realme': (255, 201, 21), 'Lenovo group': (225, 20, 10), 'LG': (153, 0, 51), 'Tecno': (0, 118, 180), # 明確に載ってなかったので、恐らくの色 'Others': (115, 66, 41), # 茶色にしてみた }
円グラフを作成する際にはわかりやすい色の方がいいだろう。線のグラフとは異なり、色がつく部分が多いからより適切な色にした方がいい。以前iPhoneの色別の人気ランキングをiPhoneの色に関係なく適当に配色した円グラフがあったがこれは見づらい。
今回はブランド名とロゴの色で検索して得たRGBの値を使用、これに透明度を後ほど追加して使用することにする。
円グラフ、レイアウト作成とグラフ保存の関数
まずは全グラフの共通事項として、円グラフの作成関数やレイアウト作成の関数、そして作成したグラフを保存するための関数を作成する。
円グラフ作成用の関数
# 円グラフ作成用の関数 def pie(labels, values, **kwargs): d = go.Pie( labels=labels, # データ名 values=values, # データ sort=False, # データを自動で降順に並び替えるのを無効に direction='clockwise', # セクターを時計回りに配置(初期はcounterclockwise) **kwargs ) return d
円グラフ作成用の関数。使用するのはgo.Pie
でデータ名はlabels
、円グラフのデータはvalues
で指定する。通常、使用されるgo.Scatter
のようにx
, y
といった表示でないので注意が必要。
また、デフォルトではvalues
が大きい順で勝手にソートされるのでsort=False
、デフォルトは反時計回りなのでdirection='clockwise'
で時計回りに変更。
**kwargs
を引数に設定することで、後から追加の引数を設定することができる。詳しくは以下。
レイアウト作成用の関数
# レイアウト作成用の関数 def layout_kwargs(**kwargs): layout = go.Layout( template=template.plotly_layout(), **kwargs, ) return layout
レイアウト作成の関数で自作のテンプレートを適用。ここでも**kwargs
とすることで後から追加の引数を設定できるようにする。
グラフ保存用の関数
# グラフ保存用の関数 def save(fig, config, save_name): pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca' pio.write_html(fig, f"{save_name}.html", config=config,) pio.write_image(fig, f"{save_name}.png")
最後は作成したグラフを保存するための関数。保存形式はhtmlとpngとした。また、configを設定することでグラフ上部のツールバーの機能を増やしたり減らしたりすることができる。が、円グラフの場合はほとんど役立たない。
円グラフの場合はホバーでの情報表示をするかどうかの選択のみできるようだ。go.Scatter
などの散布図の場合は図形を追加したりできる。
-
-
【plotly&config】グラフのツールバーを編集する
続きを見る
円グラフ作成の関数
本題の円グラフ作成用の関数を紹介。先程の準備の関数を使用しつつサッと円グラフを作成できるようにした。
各ブランドの色を対応づける関数
# 作成したい円グラフの各セクターの色を自動で取得 def sector_color(data): colors = [] for name in data: color = color_dct[name] + (0.5,) # 透明度の追加 rgba = f"rgba{color}" colors.append(rgba) return colors
まず初めは各ブランドの色をデータに対応づける関数。color_dct
で定義したブランド名と実際に使用する出荷台数のデータのブランドは完全一致しているわけではなく、順番も異なる。
したがって、この関数でデータにどのブランドが含まれているのかを抽出し、色を選択、透明度を付与したのちに配列に入れる。あとはこれを色として使用すればいい。
各セクターの色を作成
# 各セクターの色を作成 def set_marker(data): # 各ブランドの色を設定 colors = sector_color(data=data) # セクターの設定 marker = dict( colors=colors, # 各セクターの色 line=dict(color="black", width=1), # 円グラフの枠線の色と太さ ) return marker
色を対応づけられたら、その色を円グラフに適用できるように整形する。円グラフの各セクターの色は引数marker
で行うことができるので、ここでも変数はmarker
とした。
各ブランドの色だけだと円グラフがわかりにくいので、セクターは全て黒線で囲ってわかりやすくなるように調節している。
円グラフとレイアウトの作成、グラフ表示と保存
def smartphone(data, save_name, quarter=None, title=None, **kwargs): # マーカーの設定 # 2020年の出荷台数は四半期ではないから、四半期の時のみqのネストを実行 if quarter is not None: data = data[f"q{quarter}"] marker = set_marker(data=data) labels = tuple(data) values = tuple(data.values()) # 円グラフ plot = [] d = pie(labels=labels, values=values, marker=marker, **kwargs) plot.append(d) # レイアウト # グラフタイトルの位置を中央に layout = layout_kwargs(title=dict(text=title, x=0.5, xanchor='center'),) # グラフの表示と保存 config = template.plotly_config() fig = go.Figure(data=plot, layout=layout) fig.show(config=config,) save(fig=fig, config=config, save_name=save_name)
ということで、最終的に上のコードで円グラフをサクッと作成することができる。各引数は以下の通り。
data
: 円グラフにしたいデータsave_name
: グラフの保存名quarter
: どの四半期かtitle
: グラフタイトル
2020年のデータは通年でクォーターがないので、引数quarter
は初期値をNone
とし、None
じゃない場合(Q1とかの場合)はdata
のクォーター部分をさらに探索するように設定した。
あとは上で解説した関数をうまく活用して簡潔に関数を作成。これで簡単に円グラフを作成することができる。
2021年のスマホ出荷台数を円グラフ化
まずは2021年のスマホ出荷台数を円グラフ化してみる。
出荷台数の率を円グラフ化
ということで、2021年の出荷台数を円グラフ化。第一四半期では上位3ブランドで50%以上を占めていることがわかりやすい。また、上位5ブランドで7割近くもシェアを獲得していることも容易に判断できる。
これが第二四半期になるとどうなるかというと2位と3位が入れ替わった。そして、上位5ブランドの合計が若干下がってしまった。他のブランドが台頭してきたということだろう。
# シェア率を円グラフに for quarter in (1, 2): # データと四半期の設定 data = share2021 # グラフの作成 smartphone( data=data, quarter=quarter, save_name=f"share2021_q{quarter}", title=f"2021Q{quarter} Global Share[%]", # グラフタイトル textinfo='label+percent', # ラベルと割合を表示 hoverinfo='label+percent', # ホバーはセクター名と割合のみ )
出荷台数本体を円グラフ化
では、出荷台数本体はどうなのか。まあ、先にこっちを出してもよかった。割合としては先ほどと同じ。単に出荷台数表示にしただけ。ただし、割合の方では恐らく四捨五入の関係で多少割合がずれている。
第二四半期だと以下のようになる。第二四半期でXiaomiが大きく前進しつつ、他のブランド下がってしまっている。なるほど、Xiaomiの快進撃がわかりやすい。
for quarter in (1, 2): # データと四半期の設定 data = shipment2021 # グラフの作成 smartphone( data=data, quarter=quarter, save_name=f"shipment2021_q{quarter}", title=f"2021Q{quarter} Global Shipment[million]", # パーセントの合計値が99なので、以下の%とは若干ずれる textinfo='label+value+percent', )
2020年の出荷台数を円グラフ化
では2020年はどうだったのか。2020年は新コロの影響で色々と生活様式が変化した年。この影響で2021年のチャートは変わったのかもしれない。2020年は2019年の影響が大きく反映されていると思われるので、どうなるのか。
シンプルに作成すると割合が数値に
2020年の割合も小数点の影響か、全割合を足しても100%にならない。したがって、各データの値をそのまま%表示したいけど、そのままだと値だけとなってしまう。どうにかして%を数値の後にくっつけたい。
# データと四半期の設定 data, quarter = share2020, None # グラフの作成 smartphone( data=data, save_name='share2020_miss', title='2020 Global Share[%]', textinfo='label+value', # %がズレているから、値で%表示したいけど、単位%がつかない hoverinfo='label+value', # %がズレているから、値で%表示したいけど、単位%がつかない )
引数textで表示する項目を増やす
ならどうすればいいのか、それは簡単。今まで通りデータを円グラフ上に表示するのではなく、自作のテキストを表示すればいい。go.Pie
の引数text
を使用すると自由に円グラフにテキストを追加できる。
以下のコードでこれを実行している。使用したい2020年のデータから%を抽出、これに「%」を追加した。
# 各データに無理矢理%を追加する percent_values = [] for value in share2020.values(): percent_values.append(f"{value}%")
あとは今まで通り円グラフを作成すればいい。2020年のデータは四半期がないからquarter
はNone
にして指定しないようにしている。
# データと四半期の設定 data, quarter = share2020, None # グラフの作成 smartphone( data=data, save_name='share2020', title='2020 Global Share[%]', textinfo='label+text', hoverinfo='label+text', text=percent_values, # 引数textで円グラフの追加テキストを設定可能 )
完成した円グラフを見てみると、昨年はHuaweiが上位にいてXiaomi、Oppo、Vivoが追随しようとしていたことがうかがえる。これが1年で一気に変わってしまうというのが巨大市場の怖いところなのか。
また、LGがスマホから撤退したので、LGも消えていくだろうけど、代わりにRealmeがどんどんシェアを伸ばしていくのだろうか。
その他、円グラフで使えそうな引数
# 使えそうな引数たち # あるセクターを中心からどれくらいはみ出させるか pull = 0 # テキストをどの位置に設定するか textposition = ("inside", "outside", "auto", "none") # +もあり textinfo = ("label", "text", "value", "percent", "none") # +もあり hoverinfo = ( "label", "text", "value", "percent", "name", "all", "none", "skip", ) # ドーナツにする時のドーナツの穴の大きさ hole = 0 # テキストを配置する方法 insidetextorientation = ("horizontal", "radial", "tangential", "auto")
最後にgo.Pie
で使えそうな引数を列挙。これらを使用した円グラフは別記事で作成する。
スマホという名の相棒と巨大市場
現在においてスマホというのは相棒とも言えるような存在となった。肌身離さず持ち歩き、サクッと写真が撮れて検索ができて色んな人とつながることが出来る。
そんなスマホで利益を獲得しようと、ありとあらゆる企業がしのぎを削っている。今まではより高性能なものが開発されてきたが、性能は体感ではわかりにくいものとなってしまった。これからは低価格の時代なのだろう。
執筆者もスマホは好きだ。なので、これからのスマホの行く末をplotly
とともに見ていければと思う。
関連記事
-
-
【plotly&ボタン】plotlyのupdatemenusにbuttonsを追加
続きを見る
-
-
【plotly&スライダー】plotlyのslidersにスライダーを追加
続きを見る
-
-
【plotly&fill】goで領域を塗りつぶし
続きを見る
-
-
【plotly&3D】goで3Dグラフを作成
続きを見る