2017-08-31 6 views
1

さまざまな出版物のアルゴリズムを比較する棒グラフを表示したいと思います。特別なデザインのmatplot libを使ってPythonで棒グラフを描く方法

データは、次のプロパティがあります出版物の

  1. 年(これは私が私のx軸になりたいものです)
  2. スコア(これはバーの高さである)
  3. データ型(この

私はこの問題を起こすのに苦労しています(第3の要求を実施していない)。ここ

は、例えば、データ及びコードである:

import numpy as np 
import matplotlib.pyplot as plt 

dtypes = ['type1', 'type2', 'type3'] 
names = ['name1','name2','name3', 'name4'] 
score = [89.2, 95.54, 85, 86] 
years = [2016, 2017, 2016, 2015] 
methods_dtype = ['type1', 'type2', 'type1', 'type1'] 
pub_years = np.unique(years) 

fig, ax = plt.subplots() 
barplot = ax.bar(years, score) 
plt.show() 

ここで最初の問題は、私は増分幅を使用してバーを移動するいくつかの例を見た(2016年の二つのバーは、互いの上にあることです、しかし、この場合、その年にどのくらいの方法があるかは事前にわかりません)。
2番目の問題は色をコーディングすることです。

入力はデータのサブセットにすぎません。複数のエントリがある年があるかもしれません(特定の年の複数の出版物)。複数のエントリを持つデータ型(このデータ型で動作する複数のメソッド)もあります。ここで

+1

1年間のデータポイントが複数ある場合は、どのように表示しますか? – wwii

+0

@wwii 1年間の複数のデータポイントは、データ型プロパティによって並べて表示されるバーとして表示する必要があります –

+0

最も簡単な解決策は 'seaborn.barplot'でしょう。 – Phlya

答えて

0

だから私は最終的にそれを解決し、他の人のために将来の参照のためのソリューションを投稿したかった:

Julienの答えに触発されました。

私がしたことは、年とデータ型の2D配列を使用して間隔を記録しながら、それぞれの棒を別々にプロットしたことでした。私はそれをさらにきれいにしました。

import numpy as np 
import matplotlib.pyplot as plt 

def autolabel(rects): 
    """ 
    Attach a text label above each bar displaying its height 
    """ 
    for rect in rects: 
     height = rect.get_height() 
     ax.text(rect.get_x() + rect.get_width()/2., height, 
       '%d' % int(height), 
       ha='center', va='bottom') 

methods =[{"name": 'name1', "score": 89.2, "year":2016, "dtype": 'type1'}, 
      {"name": 'name2', "score": 95.54, "year":2017, "dtype": 'type2'}, 
      {"name": 'name3', "score": 85, "year":2016, "dtype": 'type1'}, 
      {"name": 'name4', "score": 86, "year":2015, "dtype": 'type1'}, 
      ] 

pub_years = np.unique([method["year"] for method in methods]) 
dtypes = np.unique([method["dtype"] for method in methods]) 
n_years = len(pub_years) 
n_dtypes = len(dtypes) 
offset = np.zeros([n_years, n_dtypes]) 
width = 0.2 
spacing = 0.01 
color_list = plt.cm.Set3(np.linspace(0, 1, n_dtypes)) 
# colors = {'type1':'b', 'type2':'g'} 
colors = {dtype: color_list[i] for i, dtype in enumerate(dtypes)} 

legend_bars = [] 
fig, ax = plt.subplots() 
for m in methods: 
    i = int(np.squeeze(np.where(pub_years==m['year']))) 
    j = int(np.squeeze([i for i, type in enumerate(dtypes) if type == m['dtype']])) 
    x = m["year"] + offset[i][j] 
    rect = ax.bar(x, m['score'], color=colors[m['dtype']], width=width) 
    autolabel(rect) 
    if offset[i][j]==0: 
     legend_bars.append(rect) 
    offset[i][j] = offset[i][j] + width + spacing 


# add some text for labels, title and axes ticks 
ax.set_ylabel('Accuracy') 
ax.set_xlabel('Year of Publication') 
ax.set_yticks(np.arange(0,105,5)) 
ax.set_ylim([0, 105]) 
ax.set_xticks(pub_years) 
ax.set_xticklabels(pub_years) 
ax.set_xlim([np.min(pub_years)- 1, np.max(pub_years) + 1]) 
ax.legend(legend_bars, dtypes) 

plt.show() 
2

は、あなたがあなたの正確なニーズに適合させるためにあなた次第、何ができるかの例です:

score = range(1,7) 
years = [2015, 2016, 2017]*2 
methods_dtype = ['type1', 'type2']*3 

color = {'type1': 'b', 'type2': 'g'} 
offset = {'type1': -0.2, 'type2': 0} 

plt.figure(1).clf() 
for s, y, m in zip(score, years, methods_dtype): 
    x = y + offset[m] 
    plt.bar(x, s, color=color[m], width=0.2) 
plt.xticks([2015, 2016, 2017], [2015, 2016, 2017]) 
+0

これは非常に役に立ちますが、まだ問題がありますオフセットを付けて同じ年に1つのタイプの複数の方法が存在する場合があります。したがって、 'methods_dtype = ['type1'、 'type2'、 'type1'] * 2 'を変更しても、望ましい出力は得られません。 –

関連する問題