2012-07-17 59 views
11

Utilizo un gráfico de barras para indicar los datos de cada grupo. Algunas de estas barras difieren significativamente entre sí. ¿Cómo puedo indicar la diferencia significativa en el diagrama de barras?Indicando la diferencia estadísticamente significativa en el gráfico de barras

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')) 

mi objetivo

enter image description here

+0

son los únicos que se hagan comparaciones a nivel local adyacente? Es decir, ¿solo desea mostrar la diferencia entre '(A, B) (B, C) (C, D)' pero no '(A, C)'? – Hooked

+0

No, me gustaría hacer una comparación entre todos los pares posibles. – imsc

+1

Puede ser difícil mostrar esto en la tabla, especialmente si hay una gran cantidad de artículos. Si tiene N = 10, ¡hay 45 comparaciones por pares diferentes! Parece que podría mostrar sus valores de p pairwise en una matriz en su lugar. ¿Esto funcionaría? – Hooked

Respuesta

14

He hecho un par de cosas aquí que sugiero cuando se trabaja con tramas complejas. Extraiga el formato personalizado en un diccionario, simplifica la vida cuando desea cambiar un parámetro, y puede pasar este diccionario a múltiples trazados. También escribí una función personalizada en annotate, y como beneficio adicional puedo anotar entre (A,C) si realmente quieres (estoy de acuerdo con mi comentario de que este no es el enfoque visual correcto, sin embargo). Es posible que necesite algunos ajustes una vez que los datos cambian, pero esto debería ponerlo en el camino correcto.

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

Muchas gracias. Muy informativo. Solo cambio 'ax.annotate (texto, xy = (X [i], y + 7), zorder = 10)' a 'ax.annotate (texto, xy = (x, y + 7), zorder = 10) 'para hacer que los valores p estén centrados. – imsc

+0

@imsc Eso es lo que usé al principio, pero esa es la ubicación del lado izquierdo del bloque de texto, no el centro del bloque de texto. Para mí, parece que están un tanto fuera de foco con esa ubicación. De cualquier manera, ¡espero que veas cómo puedes modificarlo! – Hooked

+1

Oh sí, también puse 'ha = 'center'' en' anotación'. – imsc

Cuestiones relacionadas