I have a list of positive and negative values and a single temperature. I am trying to plot the Maxwell-Boltzmann Distribution using the equation for particles moving in only one direction.
m_e = 9.11E-28 # electron mass [g]
k = 1.38E-16 # boltzmann constant [erg*K^-1]
v = range(1e10, -1e10, step=-1e8) # velocity [cm/s]
T_M = 1e6 # temperature of Maxwellian [K]
function Maxwellian(v_Max, T_Max)
normal = (m_e/(2*pi*k*T_Max))^1.5
exp_term = exp(-((m_e).*v_Max.*v_Max)/(3*k*T_Max))
return normal*exp_term
end
# Initially comparing chosen distribution f_s to Maxwellian F_s
plot(v, Maxwellian.(v, T_M), label= L"F_s" * " (Maxwellian)")
xlabel!("velocity (cm/s)")
ylabel!("probability density")
However, when, plotting this, my whole function is 0:
I tested out if I wrote my function correctly by replacing return normal*exp_term with return exp_term (i.e. ignoring any normalization constants) and this seems to produce the distinct of the bell curve:
Yet, without the normalization constant, this will not preserve the area under the curve. I was wondering what may I be doing incorrectly with setting up my Maxwellian function and the constant in front of the exponential.
If you print the normalization term on its own:
julia> (m_e/(2*pi*k*T_M))^1.5
1.0769341115495682e-27
you can see that it is 10 orders of magnitude smaller than the Y-axis scale used for the plot. You can set the Y-axis limits during the plots with ylims argument, or after the plot with:
julia> ylims!(-1e-28, 2e-27)
which changes the plot to:
Related
I want to plot in Maple the solutions to the equation (x-y)^2+(1-z)^2=0.
However, implicitplot3d is not able to plot them, at least using the default arguments. Any recommendations?
I know a priori that the set of solutions is going to be a curve contained in a plane, because I want to plot solutions of equations of the form 'f(x,y)^2+(z-1)^2=0'. Where 'f(x,y)' is a polynomial.
If x, y, and z are all real then those two squares must both equal zero, and thus z=1.
In that case you can simply utilize the implicitplot command for a 2-D plot of f(x,y)=0, and if you wish you can transform that to a 3-D plot with z=1.
restart;
with(plots,display): with(plots,implicitplot):
with(plottools,transform):
eqn := (x-y)^2+(1-z)^2 = 0:
P2D := implicitplot(eval(eqn,z=1)):
display(transform((x,y)->[x,y,1])(P2D),
labels=[x,y,z]);
eqn := (x^2-y)^2+(1-z)^2 = 0:
P2D := plots:-implicitplot(eval(eqn,z=1)):
display(transform((x,y)->[x,y,1])(P2D),
labels=[x,y,z]);
I'm working with two plots of density as a function of distance on IDL. What I'd like to do with them is convert them into plots of distance as a function of density and plot their difference, in order to obtain the shift in distance as a function of density. The issue I'm having is that one of the equations for density as a function of distance is non invertible.
Any idea on what I could do to overcome this problem?
Thanks in advance. Here are the tewo plots that I'm trying to invert and take the difference of.
lowe = ALOG10(10.)
uppe = ALOG10(170.)
re = DINDGEN(100)*(uppe - lowe)/(100 - 1L) + lowe
r = 10^(re)
loweB = ALOG10(10.)
uppeB = ALOG10(170.)
reB = DINDGEN(100)*(uppeB - loweB)/(100 - 1L) + loweB
rB = 10^(reB)
pl = plot(r,density_r(r), /XLOG, /YLOG)
plB = plot(r,freq_ratB(r), /OVERPLOT, /XLOG, /YLOG)
end
FUNCTION density_r, r
return, 4.8e9/r^14 + 3e8/r^6 + 1.4e6/r^2.3
END
FUNCTION freq_ratB, r
return, 10.*(r/215.)^(-2.8)
END
It is easy to plot distance as a function of density — just change the order of the arguments to plot, i.e.:
p_r = plot(density_r(r), r, /xlog, /ylog)
plB_r = plot(freq_ratB(r), r, /overplot, /xlog, /ylot)
But to subtract the two plots, the x-coordinates of your difference plot must be the same for the two operands of the difference. You can write an equation to invert one of your functions:
; intvert freq_ratB
function r_freq_ratB, density
compile_opt strictarr
return, 215.0 * exp((alog(density) - log(10.0)) / (-2.8))
end
So then you can plot the difference:
p_difference = plot(density, r - r_freq_ratB(density))
If you couldn't invert one of your functions, e.g., you were plotting observational data, then you would have to interpolate.
The logistic map (a map is a function that takes its value at any time step to its value at the next time step) is a model that has its roots in the prediction of animal population sizes. It has become famous, in part, due to special cases of its parameterization that exhibit surprising chaotic behavior. The logistic map equation is
xi+1 = rxi(1 - xi)
where xi ∈ [0,1] is the value ratio of current population size to maximum possible size at time i, xi+1 is the ratio at the next generation and r is the driving rate, representing animal reproduction and death. For r < 3.5 the population eventually reaches a stable size or will oscillate between a set of fixed values. However, if r > 3.5 then the system destabilizes and exhibits chaotic behavior!
That is background or context for the following problem statement:
Generate a set of points S = {r, x} where, for each r ∈ [1.0, 4.1] by increments of 0.001025 there will be a sequence of xi values for i = 0,...,16. So, for each r value there will be 17 xi values. Use x0 = 0.01. Depending on your implementation, you may find the rbind function useful. It may take a few seconds for the code to run since it will generate a lot of points in S. No more than 10 lines of R code.
Admittedly, this is a lab assignment; however, I am not a student in the class. I am learning R, and I am trying to work through the online assignments and come up with a solution myself. I have tried to create the set of points to plot, and based on manual verification of a few points, the set looks accurate.
for(j in c(0:3024)) {
rm(x)
x <- 1:17
x[1] <- 0.01
r <- 1 + (j * 0.001025)
for(i in c(1:(17-1))) {
x[i+1] <- r *x[i] * (1 - x[i])
}
if (j==0) {
binded <- cbind(r,x)
} else {
binded <- rbind(binded, cbind(r,x))
}
}
When I invoke plot(binded, pch='.') RStudio displays the result as a straight line. So I am unsure if I am using plot correctly, or even if I am generating all the points correctly. If I decrease the maximum value of j to something less than 2000, you will see a plot; it is just when the j value iterates up to 3024 that you only plot a straight line.
I believe your code is correct, what happens is when time exceeds 4, the of iterations are widely unstable and are going to -infinity. This large variation in the y value is compressing the scale and making the plot look like a flat line.
Cutting off the tail end of the matrix makes a very interesting plot:
plot(binded[-which(binded[,2]<0),], pch=".")
If you do want to plot the entire matrix, consider manually setting your y-axis limits to [0,1]. This way, the plot won't be stretched down to -1e24.
As an added bonus, here's a version in a different plotting library that has points colored by i.
I have a multi-parameter function on which I infer the parameters using MCMC. This means that I have many samples of the parameters, and I can plot the functions:
# Simulate some parameters. Really, I get these from MCMC sampling.
first = rnorm(1000) # a
second = rnorm(1000) # b
# The function (geometric)
geometric = function(x, a, b) b*(1 - a^(x + 1)/a)
# Plot curves. Perhaps not the most efficient way, but it works.
curve(geometric(x, first[1], second[1]), ylim=c(-3, 3)) # first curve
for(i in 2:length(first)) {
curve(geometric(x, first[i], second[i]), add=T, col='#00000030') # add others
}
How do I make this into a density plot instead of plotting the individual curves? For example, it's hard to see just how much denser it is around y=0 than around other values.
The following would be nice:
The ability to draw observed values on top (points and lines).
Drawing a contour line in the density, e.g. the 95% Highest Posterior Density interval or the 2.5 and 97.5 quantiles.
I have an algorithm that uses an x,y plot of sorted y data to produce an ogive.
I then derive the area under the curve to derive %'s.
I'd like to do something similar using kernel density estimation. I like how the upper/lower bounds are smoothed out using kernel densities (i.e. the min and max will extend slightly beyond my hard coded input).
Either way... I was wondering if there is a way to treat an ogive as a type of cumulative distribution function and/or use kernel density estimation to derive a cumulative distribution function given y data?
I apologize if this is a confusing question. I know there is a way to derive a cumulative frequency graph (i.e. ogive). However, I can't determine how to derive a % given this cumulative frequency graph.
What I don't want is an ecdf. I know how to do that, and I am not quite trying to capture an ecdf. But, rather integration of an ogive given two intervals.
I'm not exactly sure what you have in mind, but here's a way to calculate the area under the curve for a kernel density estimate (or more generally for any case where you have the y values at equally spaced x-values (though you can, of course, generalize to variable x intervals as well)):
library(zoo)
# Kernel density estimate
# Set n to higher value to get a finer grid
set.seed(67839)
dens = density(c(rnorm(500,5,2),rnorm(200,20,3)), n=2^5)
# How to extract the x and y values of the density estimate
#dens$y
#dens$x
# x interval
dx = median(diff(dens$x))
# mean height for each pair of y values
h = rollmean(dens$y, 2)
# Area under curve
sum(h*dx) # 1.000943
# Cumulative area
# cumsum(h*dx)
# Plot density, showing points at which density is calculated
plot(dens)
abline(v=dens$x, col="#FF000060", lty="11")
# Plot cumulative area under curve, showing mid-point of each x-interval
plot(dens$x[-length(dens$x)] + 0.5*dx, cumsum(h*dx), type="l")
abline(v=dens$x[-length(dens$x)] + 0.5*dx, col="#FF000060", lty="11")
UPDATE to include ecdf function
To address your comments, look at the two plots below. The first is the empirical cumulative distribution function (ECDF) of the mixture of normal distributions that I used above. Note that the plot of this data looks the same below as it does above. The second is a plot of the ECDF of a plain vanilla normal distribution, mean=0, sd=1.
set.seed(67839)
x = c(rnorm(500,5,2),rnorm(200,20,3))
plot(ecdf(x), do.points=FALSE)
plot(ecdf(rnorm(1000)))