2017-10-19 110 views
0

我的問題是關於這個其他問題How to use factorplot to annotate bars with categorical values or to plot 4 variables?爲什麼這個雙x軸重複兩次?

我設法把酒吧放在一起,並把第二軸。但它只適用於Clf列中有2個值的情況。用4個值,x軸重複兩次。所以不是有5組4個酒吧,我得到10組2個酒吧?請檢查圖像以瞭解問題。

我認爲這個問題是在這個代碼行:

pos = np.arange(0,l) % (l//2) + (np.arange(0,l)//(l//2)-1)*0.4 
ax.bar(pos, df["Max_Acc"], width=0.4, align="edge", ec="k", color=colors) 
handles=[plt.Rectangle((0,0),1,1, color=palette[i], ec="k") for i in range(len(uelec))] 

但我真的不知道如何解決它。

#CODE FOR THE DATAFRAME 
raw_data = {'Max_Acc': [90.71, 87.98, 92.62, 78.93, 73.69, 
         92.62, 94.17, 92.62, 83.81, 79.76, 
         85.36, 89.23, 88.88, 56.23, 89.54, 
         36.25, 14.52, 85.45, 75.45, 45.54], 
      'Stage': ['AWA', 'Rem', 'S1', 'S2', 'SWS', 
         'AWA', 'Rem', 'S1', 'S2', 'SWS', 
         'AWA', 'Rem', 'S1', 'S2', 'SWS', 
         'AWA', 'Rem', 'S1', 'S2', 'SWS'], 
      'Elec': ['Fp1', 'Fp2', 'C4', 'Cz', 'Pz', 
        'C4', 'T3', 'Fp1', 'P4', 'Fp2', 
        'Cz', 'P3', 'P4', 'T4', 'Cp1', 
        'Cp2', 'T3', 'T4', 'Fp2', 'Fp1'], 
      'Clf': ['RF', 'RF', 'RF', 'RF', 'RF', 
        'XG', 'XG', 'XG', 'XG', 'XG', 
        'SVM','SVM','SVM','SVM','SVM', 
        'KNN','KNN','KNN','KNN','KNN']} 

df=pd.DataFrame(raw_data, columns = ['Max_Acc', 'Stage', 'Elec', 'Clf']) 
df 


#CODE FOR THE PLOT 
#To use seaborn palette 
palette = sns.color_palette("Set1", 12) 
sns.set(style="white") 

uelec, uind = np.unique(df["Elec"], return_inverse=1) 
cmap = plt.cm.get_cmap("Set1") 

colors= [ palette[i] for i in uind] 
fig, ax=plt.subplots(figsize=(15, 5)) 
l = len(df) 
pos = np.arange(0,l) % (l//2) + (np.arange(0,l)//(l//2)-1)*0.4 

ax.bar(pos, df["Max_Acc"], width=0.4, align="edge", ec="k", color=colors) 

handles=[plt.Rectangle((0,0),1,1, color=palette[i], ec="k") for i in range(len(uelec))] 

legend=ax.legend(bbox_to_anchor=(0., 1.15, 1., .102), handles=handles, labels=list(uelec), 
    prop ={'size':10}, loc=9, ncol=8, title=r'Best algorithm using Max_Acc after undersampling') 

legend.get_frame().set_linewidth(0.0) 
plt.setp(legend.get_title(),fontsize='24') 

ax.set_xticks(range(l//2)) 
ax.set_xticklabels(df["Stage"][:l//2]) 
ax.set_ylim(0, 110) 
ax.get_yaxis().set_visible(False) 
ax.spines['top'].set_visible(False) 

#Double x-axis 
ax.set_xticks(pos+0.2, minor=True) 
clf=df['Clf'].tolist() 
ax.set_xticklabels(clf, minor=True) 
plt.setp(ax.get_xticklabels(), rotation=0) 
ax.tick_params(axis='x', which='major', pad=25, size=0) 

ax=ax 
def annotateBars(row, ax=ax): 
    for p in ax.patches: 
     ax.annotate("%.2f" % p.get_height(), (p.get_x() + p.get_width()/2., p.get_height()), 
      ha='center', va='center', fontsize=11, color='gray', rotation=90, xytext=(0, 20), 
      textcoords='offset points') 

plot = df.apply(annotateBars, ax=ax, axis=1) 

IMAGE我得到 IMAGE I GET

形象應該是:

enter image description here

+0

你忘了告訴怎樣的情節從給定的數據幀產生的。 – ImportanceOfBeingErnest

+0

如果您在其他(鏈接)問題中使用代碼,我認爲問題出在您的'pos'數組。打印出來,並思考它應該是什麼...在這一刻被分成兩半,我想這將導致你在這裏遇到的問題 – tom

+0

@ImportanceOfBeingErnest我已經添加了整個代碼。 – Aizzaac

回答

1

要繪製有多個標籤,可能是指this question分組的barplot。爲了能夠將數據框簡單地繪製爲分組條形圖,您可以旋轉數據幀,一次爲值,一次爲算法。然後,您可以創建算法名稱與可以通過色彩映射應用的數字的唯一映射。最好選擇超過11種不同顏色的色彩地圖。

import matplotlib.pyplot as plt 
import pandas as pd 

#CODE FOR THE DATAFRAME 
raw_data = {'Max_Acc': [90.71, 87.98, 92.62, 78.93, 73.69, 
         92.62, 94.17, 92.62, 83.81, 79.76, 
         85.36, 89.23, 88.88, 56.23, 89.54, 
         36.25, 14.52, 85.45, 75.45, 45.54], 
      'Stage': ['AWA', 'Rem', 'S1', 'S2', 'SWS', 
         'AWA', 'Rem', 'S1', 'S2', 'SWS', 
         'AWA', 'Rem', 'S1', 'S2', 'SWS', 
         'AWA', 'Rem', 'S1', 'S2', 'SWS'], 
      'Elec': ['Fp1', 'Fp2', 'C4', 'Cz', 'Pz', 
        'C4', 'T3', 'Fp1', 'P4', 'Fp2', 
        'Cz', 'P3', 'P4', 'T4', 'Cp1', 
        'Cp2', 'T3', 'T4', 'Fp2', 'Fp1'], 
      'Clf': ['RF', 'RF', 'RF', 'RF', 'RF', 
        'XG', 'XG', 'XG', 'XG', 'XG', 
        'SVM','SVM','SVM','SVM','SVM', 
        'KNN','KNN','KNN','KNN','KNN']} 

df=pd.DataFrame(raw_data, columns = ['Max_Acc', 'Stage', 'Elec', 'Clf']) 

# pivot the dataframe for values and algorithims 
df2= pd.pivot(df["Stage"], df['Clf'], df['Max_Acc']) 
df3= pd.pivot(df["Stage"], df['Clf'], df['Elec']) 

# maping between unique algorithms and some numbers 
mapping = dict(zip(df['Elec'].unique(), range(len(df['Elec'].unique())))) 
df4 = df3.applymap(lambda x: mapping[x]) 
palette = plt.cm.tab20 


# plot the grouped barplot 
ax = df2.plot(kind="bar") 

# create positions, colorize bars and annotate bars 
pos = [] 
for (bar, ind) in zip(ax.patches, df4.values.T.flatten()): 
    pos.append(bar.get_x()+bar.get_width()/2.) 
    bar.set_color(palette(ind)) 
    ax.annotate("%.2f"%bar.get_height(), (bar.get_x()+bar.get_width()/2., 
              bar.get_height()), 
      ha='center', va='center', fontsize=10, color='gray', 
      rotation=90, xytext=(0, 20), textcoords='offset points') 

# Label minor ticks 
ax.set_xticks(pos,minor=True) 
lab = [] 
for i in range(len(pos)): 
    l = df2.columns.values[i//len(df2.index.values)] 
    lab.append(l) 

ax.set_xticklabels(lab,minor=True, rotation=90) 
ax.tick_params(axis='x', which='major', pad=30, size=0) 
plt.setp(ax.get_xticklabels(), rotation=0) 

# legend 
handle = lambda ind : plt.Rectangle([0,0],0,0,color=palette(ind)) 
h, l = zip(*[(handle(ind), la) for (la, ind) in mapping.items() ]) 

legend=ax.legend(handles=h, labels=l, bbox_to_anchor=(0., 1.15, 1., .102), 
    prop ={'size':10}, loc=9, ncol=6, columnspacing=1, 
    title=r'Best algorithm using Max_Acc after undersampling') 

# layout 
plt.tight_layout() 
plt.subplots_adjust(top=0.8) 

ax.set_ylim(0, 120) 
ax.get_yaxis().set_visible(False) 
ax.spines['top'].set_visible(False) 

plt.show() 

enter image description here

+0

謝謝。但是,你知道我該如何讓這些酒吧更接近? – Aizzaac

+0

'pandas.plot.bar()'有一個可以使用的'width'參數。即'width = 1'將在組之間留下空間。 'width = 0.5'應該是默認值。如果你在兩者之間選擇一些東西,間距就會減小。 – ImportanceOfBeingErnest

+0

好的。我把它放在這一行:'ax = df2.plot(kind =「bar」,width = 0.8' – Aizzaac