2016-07-29 3 views
2

J'ai données (pd série) qui ressemble (le rendement des actions par jour, n = 555):Impossible d'obtenir l'axe y sur l'histogramme Matplotlib aux probabilités d'affichage

S = perf_manual.returns 
S = S[~((S-S.mean()).abs()>3*S.std())] 

2014-03-31 20:00:00 0.000000 
2014-04-01 20:00:00 0.000000 
2014-04-03 20:00:00 -0.001950 
2014-04-04 20:00:00 -0.000538 
2014-04-07 20:00:00 0.000764 
2014-04-08 20:00:00 0.000803 
2014-04-09 20:00:00 0.001961 
2014-04-10 20:00:00 0.040530 
2014-04-11 20:00:00 -0.032319 
2014-04-14 20:00:00 -0.008512 
2014-04-15 20:00:00 -0.034109 
... 

J'aimerais générer un diagramme de distribution de probabilité de ceci. L'utilisation:

print stats.normaltest(S) 

n, bins, patches = plt.hist(S, 100, normed=1, facecolor='blue', alpha=0.75) 
print np.sum(n * np.diff(bins)) 

(mu, sigma) = stats.norm.fit(S) 
print mu, sigma 
y = mlab.normpdf(bins, mu, sigma) 
plt.grid(True) 
l = plt.plot(bins, y, 'r', linewidth=2) 

plt.xlim(-0.05,0.05) 
plt.show() 

-je obtenir les éléments suivants:

NormaltestResult(statistic=66.587382579416982, pvalue=3.473230376732532e-15) 
1.0 
0.000495624926242 0.0118790391467 

graph

J'ai l'impression de l'axe y est un nombre, mais je voudrais avoir des probabilités à la place. Comment je fais ça? J'ai essayé beaucoup de réponses StackOverflow et je n'arrive pas à le comprendre.

+0

Etes-vous sûr que ce sont des chefs d'accusation? Je suppose que ce sont des valeurs de densité de probabilité puisque votre graphique est normalisé à 1 lorsque vous l'intégrez. La plage de vos valeurs x est juste très petite. – jotasi

+0

Pourrait être, les densités de probabilité ne sont pas mon point le plus fort. Comment puis-je au moins en faire des pourcentages? –

+0

Quels pourcentages voulez-vous avoir? Pour chaque bac, la probabilité que des données soient dans cette case? La densité de probabilité signifie essentiellement que l'intégrale sur la densité pour une certaine gamme x vous donne la probabilité de cette gamme. – jotasi

Répondre

2

Il n'y a pas de moyen facile (que je connais) de le faire en utilisant plt.hist. Mais vous pouvez simplement bin les données en utilisant np.histogram, puis normaliser les données comme vous le souhaitez. Si je vous ai bien compris, vous voulez que les données affichent la probabilité de trouver un point dans une case donnée, PAS la distribution de probabilité. Cela signifie que vous devez mettre à l'échelle vos données pour que la somme soit supérieure à toutes les classes. Cela peut simplement être fait en faisant bin_probability = n/float(n.sum()).

Vous n'aurez plus alors de fonction de distribution de probabilité correctement normalisée (pdf), ce qui signifie que l'intégrale sur un intervalle ne sera pas une probabilité! C'est la raison pour laquelle vous devez redimensionner votre mlab.normpdf pour avoir la même norme que votre histogramme. Le facteur requis est juste la largeur du bac, car lorsque vous commencez à partir du pdf binning correctement normalisé, la somme sur tous les bacs fois leur largeur respective est 1. Maintenant vous voulez avoir juste la somme des bacs égale à 1. Donc le facteur d'échelle est la largeur de la poubelle.

Par conséquent, le code que vous retrouvez avec quelque chose le long des lignes de:

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

# Produce test data 
S = np.random.normal(0, 0.01, size=1000) 

# Histogram: 
# Bin it 
n, bin_edges = np.histogram(S, 100) 
# Normalize it, so that every bins value gives the probability of that bin 
bin_probability = n/float(n.sum()) 
# Get the mid points of every bin 
bin_middles = (bin_edges[1:]+bin_edges[:-1])/2. 
# Compute the bin-width 
bin_width = bin_edges[1]-bin_edges[0] 
# Plot the histogram as a bar plot 
plt.bar(bin_middles, bin_probability, width=bin_width) 

# Fit to normal distribution 
(mu, sigma) = stats.norm.fit(S) 
# The pdf should not normed anymore but scaled the same way as the data 
y = mlab.normpdf(bin_middles, mu, sigma)*bin_width 
l = plt.plot(bin_middles, y, 'r', linewidth=2) 

plt.grid(True) 
plt.xlim(-0.05,0.05) 
plt.show() 

Et l'image résultante sera:

enter image description here

+0

Merci pour cela et dissiper ma confusion :) –