wafflechart







まず初めに

matplotlibと、pywaffleをpip installでインストールしておきます。

pip install pywaffle

pip install matplotlib

In [1]:
import matplotlib.pyplot as plt
from pywaffle import Waffle

親切なwarningを消します。(通常は不要です)

In [2]:
import warnings
warnings.filterwarnings('ignore')

簡単なワッフルチャートを作る

valuesというところに、データを入れてください。合計して100にならなくても大丈夫です。

In [3]:
fig = plt.figure(
    FigureClass=Waffle, 
    rows=10, 
    columns=10, 
    values=[29, 60, 11],
    figsize=(5, 5),
    colors=["#f3d2c1", "#8bd3dd", "#f582ae"]
)
plt.show()

説明を入れたワッフルチャートを作る

まず、データを作成します。データは、犬派、猫派、ウサギ派の割合です。もちろん空想の数値です。
パラメータを少し説明します。

  • legendのbbox_to_anchorの数値を変えるとlegendの位置が変わります。
  • locはbest,upper right,upper left,lower left,lower right,right,center left,center right,lower center,upper center,centerのどれかを選択します。
  • starting_locationはNW,SW,NE,SEのどれかです。東西南北で、開始位置を指定します。
  • block_arranging_styleは、normal,snake,new-lineのいずれかです。ここをいじってみます。

block_arranging_style = ‘normal’ の場合

In [4]:
data = {'Dog person': 29, 'Cat person': 60, 'Rabbit person': 11}

fig = plt.figure(
    FigureClass=Waffle, 
    rows=8, 
    values=data, 
    colors=["#f3d2c1", "#8bd3dd", "#f582ae"],
    title={'label': 'Dog, Cat, or Rabbit person?', 'loc': 'center'},
    labels=[f"{k} ({v}%)" for k, v in data.items()],
    legend={'loc': 'lower left', 'bbox_to_anchor': (-0.1, -0.1), 'ncol': len(data), 'framealpha': 0},
    starting_location='SW',
    block_arranging_style='normal',
    figsize=(6, 6)
)

plt.show()

block_arranging_style = ‘snake’ の場合

In [5]:
data = {'Dog person': 29, 'Cat person': 60, 'Rabbit person': 11}

fig = plt.figure(
    FigureClass=Waffle, 
    rows=8, 
    values=data, 
    colors=["#f3d2c1", "#8bd3dd", "#f582ae"],
    title={'label': 'Dog, Cat, or Rabbit person?', 'loc': 'center'},
    labels=[f"{k} ({v}%)" for k, v in data.items()],
    legend={'loc': 'lower left', 'bbox_to_anchor': (-0.1, -0.1), 'ncol': len(data), 'framealpha': 0},
    starting_location='SW',
    block_arranging_style='snake',
    figsize=(6, 6)
)

plt.show()

block_arranging_style = ‘new-line’ の場合

In [6]:
data = {'Dog person': 29, 'Cat person': 60, 'Rabbit person': 11}

fig = plt.figure(
    FigureClass=Waffle, 
    rows=8, 
    values=data, 
    colors=["#f3d2c1", "#8bd3dd", "#f582ae"],
    title={'label': 'Dog, Cat, or Rabbit person?', 'loc': 'center'},
    labels=[f"{k} ({v}%)" for k, v in data.items()],
    legend={'loc': 'lower left', 'bbox_to_anchor': (-0.1, -0.1), 'ncol': len(data), 'framealpha': 0},
    starting_location='SW',
    block_arranging_style='new-line',
    figsize=(6, 6)
)

plt.show()

インフォグラフィック(ピクトグラム)で表現

pywaffleは、font awesomeというウェブサイトの作ったフリーのアイコンが内蔵されています。つまり、以下のサイトでフリーで使えるアイコンはすべて使えます。フリーで使えるアイコン名を調べて、icon=” “に入れれば、使えます。すごい。
https://fontawesome.com/icons?d=gallery
例えば、male, dog, cat とか、結構種類多いです。

In [7]:
data = {'Dog person': 29, 'Cat person': 60, 'Rabbit person': 11}
fig = plt.figure(
    FigureClass=Waffle, 
    rows=10, 
    values=data, 
    colors=["#f3d2c1", "#8bd3dd", "#f582ae"],
    legend={'loc': 'center'},
    icons='user', 
    icon_size=20,
    icon_style="regular",
    icon_legend=True,
    figsize=(5, 5)
)
plt.show()

複数の都市での犬派、猫派、ウサギ派の割合を表示

実際の数値ではありません。
まずは、データを作ります。アンケートに全人口が回答したという前提です。
データフレームを扱うので、pandasをimportします。

In [8]:
import pandas as pd

data = pd.DataFrame(
    {
        'labels': ['Dog person', 'Cat person', 'Rabbit person'],
        'Tokyo': [1669093, 5100007, 2503639],
        'Osaka': [915002, 1184121, 592060],
        'Sapporo':[1073795,780942,97617],
        'Fukuoka': [953982, 369283, 215415],
        
    })

data
Out[8]:
labels Tokyo Osaka Sapporo Fukuoka
0 Dog person 1669093 915002 1073795 953982
1 Cat person 5100007 1184121 780942 369283
2 Rabbit person 2503639 592060 97617 215415

割合を計算して列に追加

四捨五入っぽいnp.roundをして、細かい数字を消します。np.round(2.5)→2 np.round(3.5)→4となるので注意。
math.floor()は、データフレームを扱えない。

In [9]:
import numpy as np
data['Tokyo%'] = ( data['Tokyo'] / data['Tokyo'].sum() ) * 100
data['Osaka%'] = ( data['Osaka'] / data['Osaka'].sum() ) * 100
data['Sapporo%'] = ( data['Sapporo'] / data['Sapporo'].sum() ) * 100
data['Fukuoka%'] = ( data['Fukuoka'] / data['Fukuoka'].sum() ) * 100

data['Tokyo%'] =np.round(data['Tokyo%'])
data['Osaka%'] =np.round(data['Osaka%'])
data['Sapporo%'] =np.round(data['Sapporo%'])
data['Fukuoka%'] =np.round(data['Fukuoka%'])
data
Out[9]:
labels Tokyo Osaka Sapporo Fukuoka Tokyo% Osaka% Sapporo% Fukuoka%
0 Dog person 1669093 915002 1073795 953982 18.0 34.0 55.0 62.0
1 Cat person 5100007 1184121 780942 369283 55.0 44.0 40.0 24.0
2 Rabbit person 2503639 592060 97617 215415 27.0 22.0 5.0 14.0

グラフを作成

In [10]:
fig = plt.figure(
    FigureClass=Waffle,
    plots={
        '411': {
            'values': data['Tokyo']/100000 ,
            'labels': ["{0}({1})".format(s,k) for s,k in zip(data['labels'],data['Tokyo%'])],
            'legend': {'loc': 'upper left', 'bbox_to_anchor': (1.05, 1), 'fontsize': 8},
            'title': {'label': 'Dog, Cat, or Rabbit person? in Tokyo', 'loc': 'left'}
        },
        '412': {
            'values': data['Osaka']/100000 ,
            'labels':  ["{0}({1})".format(s,k) for s,k in zip(data['labels'],data['Osaka%'])],
            'legend': {'loc': 'upper left', 'bbox_to_anchor': (1.2, 1), 'fontsize': 8},
            'title': {'label': 'Dog, Cat, or Rabbit person? in Osaka', 'loc': 'left'}
        },
        '413': {
            'values': data['Sapporo']/100000 ,
            'labels':  ["{0}({1})".format(s,k) for s,k in zip(data['labels'],data['Sapporo%'])],
            'legend': {'loc': 'upper left', 'bbox_to_anchor': (1.2, 1), 'fontsize': 8},
            'title': {'label': 'Dog, Cat, or Rabbit person? in Sapporo', 'loc': 'left'}
        },
        '414': {
            'values': data['Fukuoka']/100000 ,
            'labels':  ["{0}({1})".format(s,k) for s,k in zip(data['labels'],data['Fukuoka%'])],
            'legend': {'loc': 'upper left', 'bbox_to_anchor': (1.3, 1), 'fontsize': 8},
            'title': {'label': 'Dog, Cat, or Rabbit person? in Fukuoka', 'loc': 'left'}
        },
    },
    rows=5,  
    colors=["#f3d2c1", "#8bd3dd", "#f582ae"],  
    figsize=(10, 10)
)
plt.show()

インフォグラフィック(ピクトグラム)で表現2

上記のパラメーターにiconsを加えたら、インフォグラフィックになります。

In [11]:
fig = plt.figure(
    FigureClass=Waffle,
    plots={
        '411': {
            'values': data['Tokyo']/100000 ,
            'labels': ["{0}({1})".format(s,k) for s,k in zip(data['labels'],data['Tokyo%'])],
            'legend': {'loc': 'upper left', 'bbox_to_anchor': (1.05, 1), 'fontsize': 8},
            'title': {'label': 'Dog, Cat, or Rabbit person? in Tokyo', 'loc': 'left'},
            'icons':'male'
        },
        '412': {
            'values': data['Osaka']/100000 ,
            'labels':  ["{0}({1})".format(s,k) for s,k in zip(data['labels'],data['Osaka%'])],
            'legend': {'loc': 'upper left', 'bbox_to_anchor': (1.2, 1), 'fontsize': 8},
            'title': {'label': 'Dog, Cat, or Rabbit person? in Osaka', 'loc': 'left'},
            'icons':'comment'
        },
        '413': {
            'values': data['Sapporo']/100000 ,
            'labels':  ["{0}({1})".format(s,k) for s,k in zip(data['labels'],data['Sapporo%'])],
            'legend': {'loc': 'upper left', 'bbox_to_anchor': (1.2, 1), 'fontsize': 8},
            'title': {'label': 'Dog, Cat, or Rabbit person? in Sapporo', 'loc': 'left'},
            'icons':'grin'
        },
        '414': {
            'values': data['Fukuoka']/100000 ,
            'labels':  ["{0}({1})".format(s,k) for s,k in zip(data['labels'],data['Fukuoka%'])],
            'legend': {'loc': 'upper left', 'bbox_to_anchor': (1.3, 1), 'fontsize': 8},
            'title': {'label': 'Dog, Cat, or Rabbit person? in Fukuoka', 'loc': 'left'},
            'icons':'heart'
        },
    },
    rows=5,  
    colors=["#f3d2c1", "#8bd3dd", "#f582ae"],  
    figsize=(10, 10)
)
plt.show()
category