Python - Matplotlib: normalize axis when plotting a Probability Density Function
the y-axis is normed in a way, that the area under the curve is one.
And adding equal weights for every data point makes no sense if you normalize anyway with normed=True
.
first you need to shift your data to 0:
lines -= mean(lines)
then plot it.
ythis should be a working minimal example:
import numpy as np
from numpy.random import normal
import matplotlib.pyplot as plt
from scipy.stats import norm
# gaussian distributed random numbers with mu =4 and sigma=2
x = normal(4, 2, 10000)
mean = np.mean(x)
sigma = np.std(x)
x -= mean
x_plot = np.linspace(min(x), max(x), 1000)
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.hist(x, bins=50, normed=True, label="data")
ax.plot(x_plot, norm.pdf(x_plot, mean, sigma), 'r-', label="pdf")
ax.legend(loc='best')
x_ticks = np.arange(-4*sigma, 4.1*sigma, sigma)
x_labels = [r"${} \sigma$".format(i) for i in range(-4,5)]
ax.set_xticks(x_ticks)
ax.set_xticklabels(x_labels)
plt.show()
output image is this:
and you have too much imports.
you import decimals
twice, one time even with *
and then numpy, pyplot and scipy are included in pylab. Also why import the whole scipy.stats and then again import just norm from it?
Comments
-
Informatico_Sano almost 4 years
I'm using Python and some of its extensions to get and plot the Probability Density Function. While I manage to plot it, in its form, at least, I don't manage to succeed on scalating the axis.
import decimal import numpy as np import scipy.stats as stats import pylab as pl import matplotlib.pyplot as plt from decimal import * from scipy.stats import norm lines=[] fig, ax = plt.subplots(1, 1) mean, var, skew, kurt = norm.stats(moments='mvsk') #Here I delete some lines aimed to fill the list with values Long = len(lines) Maxim = max(lines) #MaxValue Minim = min(lines) #MinValue av = np.mean(lines) #Average StDev = np.std(lines) #Standard Dev. x = np.linspace(Minim, Maxim, Long) ax.plot(x, norm.pdf(x, av, StDev),'r-', lw=3, alpha=0.9, label='norm pdf') weights = np.ones_like(lines)/len(lines) ax.hist(lines, weights = weights, normed=True, histtype='stepfilled', alpha=0.2) ax.legend(loc='best', frameon=False) plt.show()
The result is
While I would like to have it expressed - In the x-axis centered in 0 and related to the standard deviation - In the y-axis, related to the histogram and the %s (normalized to 1)
For the x-axis as the image belowAnd like this last image for the y-axis
I've managed to escalate the y-axis in a histogram by plotting it individually with the instruction weights = weights and setting it into the plot, but I can't do it here. I include it in the code but actually it does nothing in this case.
Any help would be appreciated
-
Informatico_Sano almost 10 yearsHi @MaxNoe and thanks for the answer. To begin with, I get the idea of substracting the average of every element, but as it is a set of values that way is not correct. I think doing
lines=[x-av for x in lines]
fixes that. Anyway, I don't manage to adapt my code to that and I manage to plot but I obtain a very bad result. You mean that I only have to 'parse' theax.plot(...)
line to your code? Could you please add the plot missing line(s) to your solution? Thanks in advance -
MaxNoe almost 10 yearsI edited the code to be a working minimal example and added the plot
-
Informatico_Sano almost 10 yearsRight, actually it does what I asked about the axis in the title and works perfectly with a histogram. Just a small problem that I face now, I can't plot the probability density function there, if I do that it losses its shape in fact. I use your mean and your st. dev, but I don't succeed with it. How should I do to add it? Thanks for your answers
-
MaxNoe almost 10 yearswhat do you mean with 'it looses its shape' ?
-
Informatico_Sano almost 10 yearsI mean that the pdf as the one I plotted in the question, when I try to adapt it to your code and plot it there, on the same figure as the histogram, the result is not a Gaussian/bell curve. I'm not sure what am I doing wrong to plot it there also...
-
MaxNoe almost 10 yearsdo you want to fit a guassian bell to the histogram? Or just Plot the gaussian bell with mu=mean(x) and sigma=std(x)?
-
MaxNoe almost 10 yearsif you use scipy.stats.norm.pdf, you will just plot a gaussian bell with mean=mean(x) and sigma=std(x). And that works for me, I edited the post.
-
Informatico_Sano almost 10 yearsFit the the histogram into the bell and measure it with %s in the y-axis, I was searching for that exactly. I have to figure out why it doesn't work my given values, but I'll work on it tonight. Thank you very much for your answers.
-
MaxNoe almost 10 yearswhat do you mean with %s? You have a continious probability function for the gaussian. If you want to completely normalize it to the standard gaussian divide the values by the standard deviation. But whats then the point? Do you want a histogram of a standard gaussian or of your data?
-
Informatico_Sano almost 10 yearsI have a set of given values, and I want the PDF function of the set measured like this: - On the x-axis, measured in function of the St. Dev. - On the y-axis, display the probability of appearance (maximum in 0*StDev) - Desirably the histogram of values fitted into it
-
MaxNoe almost 10 yearsthe probability density is not the probability of appearance at this point, so your y-axis cannot be the probability of appearance if you plot an unbinned pdf. If you integrate the pdf over a delta, you get the probability of appearance for this delta.
-
Informatico_Sano over 9 yearsHi again Max, do you know how to 'cut' the plot of the histogram between two limits while mantaining the P.D.F the exact way as it is now? For example drawing the histogtam here between -2*sigma and 2*sigma. Thanks in advance.
-
MaxNoe over 9 yearsYou can give it the range option. ,
range=[-2*sigma,2 *sigma]