2012-07-17 7 views
11

Ich verwende ein Balkendiagramm, um die Daten jeder Gruppe anzuzeigen. Einige dieser Balken unterscheiden sich erheblich voneinander. Wie kann ich den signifikanten Unterschied im Balkendiagramm angeben?Anzeige des statistisch signifikanten Unterschieds im Balkendiagramm

import numpy as np 
import matplotlib.pyplot as plt 
menMeans = (5, 15, 30, 40) 
menStd  = (2, 3, 4, 5) 
ind = np.arange(4) # the x locations for the groups 
width=0.35 
p1 = plt.bar(ind, menMeans, width=width, color='r', yerr=menStd) 
plt.xticks(ind+width/2., ('A', 'B', 'C', 'D')) 

Ich bin mit dem Ziel für

enter image description here

+0

sind die einzigen Vergleiche lokal benachbarten gemacht werden? Willst du also nur den Unterschied zwischen (A, B) (B, C) (C, D), aber nicht (A, C) zeigen? – Hooked

+0

Nein, ich möchte einen Vergleich zwischen allen möglichen Paaren machen. – imsc

+1

Es kann schwierig sein, dies auf dem Chart anzuzeigen, besonders wenn es eine große Anzahl von Elementen gibt. Wenn Sie N = 10 haben, gibt es 45 verschiedene paarweise Vergleiche! Es scheint, als könnten Sie stattdessen Ihre paarweisen p-Werte auf einer Matrix anzeigen. Würde das funktionieren? – Hooked

Antwort

14

Ich habe hier ein paar Dinge getan, die ich vorschlagen, wenn sie mit komplexen Plots arbeiten. Ziehen Sie die benutzerdefinierte Formatierung in ein Wörterbuch ein. Dadurch wird das Leben einfacher, wenn Sie einen Parameter ändern möchten - und Sie können dieses Wörterbuch an mehrere Diagramme übergeben. Ich habe auch eine benutzerdefinierte Funktion annotate die Itervalues ​​geschrieben, als Bonus kann es zwischen (A,C) kommentieren, wenn Sie wirklich wollen (ich stehe zu meinem Kommentar, dass dies nicht der richtige visuelle Ansatz ist). Es kann einige Anpassungen erfordern, sobald sich die Daten ändern, aber dies sollte Sie auf den richtigen Weg bringen.

import numpy as np 
import matplotlib.pyplot as plt 
menMeans = (5, 15, 30, 40) 
menStd  = (2, 3, 4, 5) 
ind = np.arange(4) # the x locations for the groups 
width= 0.7 
labels = ('A', 'B', 'C', 'D') 

# Pull the formatting out here 
bar_kwargs = {'width':width,'color':'y','linewidth':2,'zorder':5} 
err_kwargs = {'zorder':0,'fmt':None,'linewidth':2,'ecolor':'k'} #for matplotlib >= v1.4 use 'fmt':'none' instead 

fig, ax = plt.subplots() 
ax.p1 = plt.bar(ind, menMeans, **bar_kwargs) 
ax.errs = plt.errorbar(ind, menMeans, yerr=menStd, **err_kwargs) 


# Custom function to draw the diff bars 

def label_diff(i,j,text,X,Y): 
    x = (X[i]+X[j])/2 
    y = 1.1*max(Y[i], Y[j]) 
    dx = abs(X[i]-X[j]) 

    props = {'connectionstyle':'bar','arrowstyle':'-',\ 
       'shrinkA':20,'shrinkB':20,'linewidth':2} 
    ax.annotate(text, xy=(X[i],y+7), zorder=10) 
    ax.annotate('', xy=(X[i],y), xytext=(X[j],y), arrowprops=props) 

# Call the function 
label_diff(0,1,'p=0.0370',ind,menMeans) 
label_diff(1,2,'p<0.0001',ind,menMeans) 
label_diff(2,3,'p=0.0025',ind,menMeans) 


plt.ylim(ymax=60) 
plt.xticks(ind, labels, color='k') 
plt.show() 

enter image description here

+1

Vielen Dank. Sehr informativ. Ich ändere einfach 'ax.annotate (Text, xy = (X [i], y + 7), zorder = 10)' zu 'ax.annotate (Text, xy = (x, y + 7), zorder = 10) 'um die p-Werte zentriert zu machen. – imsc

+0

@imsc Das ist, was ich zuerst verwendet habe, aber das ist die Position der linken Seite des Textblocks - nicht die Mitte des Textblocks. Für mich scheint es, dass das bei dieser Platzierung etwas dezentriert ist. Wie auch immer, ich hoffe, du siehst, wie du dich zwicken kannst! – Hooked

+1

Oh ja, ich habe auch 'ha = 'center' in' annotieren' gesetzt. – imsc