2011-06-13 4 views
4

I ont plusieurs ensembles de données (distribution) comme suit:Python: Matplotlib - terrain de probabilité pour plusieurs ensemble de données

set1 = [1,2,3,4,5] 
set2 = [3,4,5,6,7] 
set3 = [1,3,4,5,8] 

Comment tracer un diagramme de dispersion avec les ensembles de données ci-dessus avec l'axe y étant probabilité (c'est-à-dire le centile de la distribution dans l'ensemble: 0% -100%) et l'axe des x étant les noms des ensembles de données? dans JMP, il est appelé 'Quantile Plot'.

Quelque chose comme l'image ci-joint: enter image description here

S'il vous plaît éduquent. Merci.

[EDIT]

Mes données est csv en tant que tel:

enter image description here

aide de l'outil d'analyse JMP, je suis en mesure de tracer la courbe de distribution de probabilité (QQ-terrain/Terrain normale quantile comme figure bien au-dessous):

enter image description here

Je crois que Joe Kington a presque résolu mon problème, mais je me demande comment traiter les données CSV brutes en tableaux de probalité ou en centiles.

Je fais cela pour automatiser certaines analyses de statistiques en Python plutôt qu'en fonction de JMP pour le traçage.

+0

si vous décrivez exactement comment convertir vos ensembles de données dans ce que vous voulez tracer, il ll sera un peu plus facile de vous aider à le faire. –

Répondre

11

Je ne suis pas tout à fait clair sur ce que vous voulez, alors je vais deviner, ici ...

Vous voulez que les valeurs « de probabilité/centiles » d'être un histogramme cumulatif?

Donc, pour un seul intrigue, vous auriez quelque chose comme ça? (Il Traçage avec des marqueurs comme vous avez montré ci-dessus, au lieu de l'intrigue étape plus traditionnelle ...)

import scipy.stats 
import numpy as np 
import matplotlib.pyplot as plt 

# 100 values from a normal distribution with a std of 3 and a mean of 0.5 
data = 3.0 * np.random.randn(100) + 0.5 

counts, start, dx, _ = scipy.stats.cumfreq(data, numbins=20) 
x = np.arange(counts.size) * dx + start 

plt.plot(x, counts, 'ro') 
plt.xlabel('Value') 
plt.ylabel('Cumulative Frequency') 

plt.show() 

enter image description here

Si c'est à peu près ce que vous voulez pour une seule parcelle, il y a plusieurs façons de faire plusieurs parcelles sur une figure. Le plus simple est simplement d'utiliser des sous-placettes.

Ici, nous générerons des ensembles de données et de tracer le graphe sur différentes intrigues secondaires avec des symboles différents ...

import itertools 
import scipy.stats 
import numpy as np 
import matplotlib.pyplot as plt 

# Generate some data... (Using a list to hold it so that the datasets don't 
# have to be the same length...) 
numdatasets = 4 
stds = np.random.randint(1, 10, size=numdatasets) 
means = np.random.randint(-5, 5, size=numdatasets) 
values = [std * np.random.randn(100) + mean for std, mean in zip(stds, means)] 

# Set up several subplots 
fig, axes = plt.subplots(nrows=1, ncols=numdatasets, figsize=(12,6)) 

# Set up some colors and markers to cycle through... 
colors = itertools.cycle(['b', 'g', 'r', 'c', 'm', 'y', 'k']) 
markers = itertools.cycle(['o', '^', 's', r'$\Phi$', 'h']) 

# Now let's actually plot our data... 
for ax, data, color, marker in zip(axes, values, colors, markers): 
    counts, start, dx, _ = scipy.stats.cumfreq(data, numbins=20) 
    x = np.arange(counts.size) * dx + start 
    ax.plot(x, counts, color=color, marker=marker, 
      markersize=10, linestyle='none') 

# Next we'll set the various labels... 
axes[0].set_ylabel('Cumulative Frequency') 
labels = ['This', 'That', 'The Other', 'And Another'] 
for ax, label in zip(axes, labels): 
    ax.set_xlabel(label) 

plt.show() 

enter image description here

Si nous voulons que ce ressembler à une parcelle continue, nous pouvons juste presser les intrigues secondaires et désactiver certaines limites. Il suffit d'ajouter les éléments suivants avant d'appeler plt.show()

# Because we want this to look like a continuous plot, we need to hide the 
# boundaries (a.k.a. "spines") and yticks on most of the subplots 
for ax in axes[1:]: 
    ax.spines['left'].set_color('none') 
    ax.spines['right'].set_color('none') 
    ax.yaxis.set_ticks([]) 
axes[0].spines['right'].set_color('none') 

# To reduce clutter, let's leave off the first and last x-ticks. 
for ax in axes: 
    xticks = ax.get_xticks() 
    ax.set_xticks(xticks[1:-1]) 

# Now, we'll "scrunch" all of the subplots together, so that they look like one 
fig.subplots_adjust(wspace=0) 

enter image description here

Espérons qui aide un peu, en tout cas!

Éditer: Si vous voulez des valeurs centiles, à la place un histogramme cumulatif (je n'aurais vraiment pas dû utiliser 100 comme taille de l'échantillon!), C'est facile à faire.

Il suffit de faire quelque chose comme ça (à l'aide numpy.percentile au lieu des choses normalisant à la main):

# Replacing the for loop from before... 
plot_percentiles = range(0, 110, 10) 
for ax, data, color, marker in zip(axes, values, colors, markers): 
    x = np.percentile(data, plot_percentiles) 
    ax.plot(x, plot_percentiles, color=color, marker=marker, 
      markersize=10, linestyle='none') 

enter image description here

+0

Bien! Incidemment, avez-vous envisagé d'envoyer certains d'entre eux à la galerie? La moitié du temps, je trouve le moyen le plus rapide de comprendre comment faire quelque chose dans matplotlib est de parcourir la galerie pour quelque chose qui lui ressemble. – DSM

+0

@Joe: La fréquence cumulée est-elle la même que les centiles? Je dois vérifier ça. Vous avez presque résolu mon problème, je peaufine ici et là pour traiter la table de données. – siva

+0

@siva - Non, ils ne le sont pas. Je n'aurais pas dû utiliser 100 comme taille d'échantillon! Cela le rend très trompeur! (Désolé pour ça!) Cependant, il est assez simple d'exprimer les valeurs de fréquence cumulatives en percentiles. Vous avez juste besoin de normaliser par le nombre d'échantillons dans l'ensemble de données. –