52797


4つのアルゴリズム：A,B,C,Dの結果の棒グラフをプロットしようとしています．  
次の例に示すように，A，Bの結果は1つの数値です．一方でCとDはアルゴリズム内に1つのパラメータkを持ち，パラメータ毎に結果があります．

例)  
A: 66%  
B: 68.5%  
C: k=1: 69%  
k=2: 73%  
k=3: 80%  
D: k=1: 72%  
k=2: 78%  
k=3: 82%

これらの結果はそれぞれのアルゴリズムに対して以下のようにnumpy.ndarrayに格納されています．  
result_A = [66]  
result_B = [68.5]  
result_C = [69, 73, 80]  
result_D = [72, 78, 82]

そして，これらを以下のようにプロットしたいと思っています．  
[![barplots](https://i.stack.imgur.com/Lx4jc.png)](https://i.stack.imgur.com/Lx4jc.png)

どのようにすればスマートにこのプロットを実現できるでしょうか？  
matplotlibもしくは（適切にDataFrameにデータを移して）pandasでの方法をご教示ください．  
※ラベルや軸については細かいことは必要としていません．


CC BY-SA 4.0
2019-02-15T08:02:28.533
52792
2019-02-15T15:05:48.357
2019-02-15T08:37:06.320
32189
32189
question
python pandas matplotlib numpy
matplotlib / pandasを用いた部分的に階層構造を持つデータの棒グラフプロット


このようなグラフを自動的に構成してくれるものが見つかりませんでしたので  
とりあえず書いてみました。  
あとは適当にカスタマイズしてください。  
barのX位置と幅の計算はもう少しシンプルになるかもしれません。

[code]

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.colors import Normalize
    
    A = np.asarray([66])
    B = np.asarray([68.5])
    C = np.asarray([69, 73, 80])
    D = np.asarray([72, 78, 82])
    label = ['A', 'B', 'C', 'D']
    
    # DataFrame化(MultiIndex)
    df = pd.concat(map(pd.Series, [A,B,C,D]), axis=1).unstack().rename('rate').dropna().to_frame()
    # 各グループ毎の値の個数
    n = df.groupby(level=0)['rate'].transform('size')
    # 各Barの幅を求める
    w = 0.8 / n
    df['width'] = w - 0.05 #気持ち細くする
    # 各Barの位置を求める
    df['pos'] = df.index.get_level_values(0) - (n - 1) * w / 2 + (df.index.get_level_values(1) * 0.8 / n)
    
    # 描画
    plt.bar(df['pos'],
            df['rate'],
            width=df['width'],
            color=plt.get_cmap("tab10")(df.index.get_level_values(0)))
    plt.xticks(range(len(label)), label)
    plt.ylabel('Rate [%]')
    plt.show()
    
[/code]

[![画像の説明をここに入力](https://i.stack.imgur.com/2tsei.png)](https://i.stack.imgur.com/2tsei.png)


CC BY-SA 4.0
2019-02-15T10:34:25.143
52797
2019-02-15T10:34:25.143
24801
52792
answer

[code]

    import matplotlib.pyplot as plt
    import numpy as np
    
    # 設定 ===========================================================
    size = (8,5) # グラフのサイズ
    width = 0.8 # 要素1個のときの幅
    gap = 0.05 # すき間
    # 色の設定(データの要素数と合わせる)
    color_list = [['r'], # result_A
                  ['b'], # result_B
                  ['forestgreen', 'g', 'darkgreen'], # result_C
                  ['y', 'gold', '#ffa500']] # result_D
    # 設定ここまで ====================================================
    
    # データ
    result_A = np.array([66])
    result_B = np.array([68.5])
    result_C = np.array([69, 73, 80])
    result_D = np.array([72, 78, 82])
    
    plt.figure(figsize=size)
    
    # データまとめる
    result = [result_A, result_B, result_C, result_D]
    for i, j in enumerate(result):
        for k in range(len(j)):
            plt.bar(i+1+width/len(j)*k-width/len(j)/2*(len(j)-1), j[k],
                    width=width/len(j)-gap, color=color_list[i][k])
    
    plt.title('Result')
    plt.xticks([1,2,3,4],['A','B','C','D'])
    plt.xlabel('Algorithm')
    plt.ylabel('%')
    plt.show()
    
[/code]

スマートじゃないかもですが、こんな感じでどうでしょうか？


CC BY-SA 4.0
2019-02-15T15:05:48.357
52799
2019-02-15T15:05:48.357
32123
52792
answer