1

I am currently trying to plot a function which describes linear perturbation growth in cosmology for different world models. I would like to be able to have all the curves on the same set of axes, but am struggling with setting it up.

My aim is to plot this function D, with respect to z, but have multiple plots with varying density parameters ($\Omega$).

I have managed two solutions but both aren't working perfectly, the first is very inefficient (adding new functions for each set of parameters):

z = np.arange(0.0,10,0.1) #density parameters MOm = 1.0 MOv = 0.0 COm = 0.3 COv = 0.7 H0 = 70 def Mf(z): A = (5/2)*MOm*(H0**2) H = H0 * np.sqrt( MOm*((1+z)**3) + MOv ) return A * ((1+z)/(H**3)) def MF(z): res = np.zeros_like(z) for i,val in enumerate(z): y,err = integrate.quad(Mf,val,np.inf) res[i] = y return res def MD(z): return (H0 * np.sqrt( MOm*((1+z)**3) + MOv )) * MF(z) def Cf(z): A = (5/2)*COm*(H0**2) H = H0 * np.sqrt( COm*((1+z)**3) + COv ) return A * ((1+z)/(H**3)) def CF(z): res = np.zeros_like(z) for i,val in enumerate(z): y,err = integrate.quad(Cf,val,np.inf) res[i] = y return res def CD(z): return (H0 * np.sqrt( COm*((1+z)**3) + COv )) * CF(z) plt.plot(z,MD(z),label="Matter Dominated") plt.plot(z,CD(z),label="Current Epoch") 

So I tried to make it simpler with a for loop, but have been unable to work out how to add labels to each plot inside the loop:

Om = (1.0,0.3) Ov = (0.0,0.7) for param1,param2 in zip(Om,Ov): def f(z): A = (5/2)*param1*(H0**2) H = H0 * np.sqrt( param1*((1+z)**3) + param2 ) return A * ((1+z)/(H**3)) def F(z): res = np.zeros_like(z) for i,val in enumerate(z): y,err = integrate.quad(f,val,np.inf) res[i] = y return res def D(z): return (H0 * np.sqrt( param1*((1+z)**3) + param2 )) * F(z) plt.plot(z,D(z)) 

Could someone please help explain an efficient method of doing so? Or how to add labels to plots on the fly with a for loop. Any help would be greatly appreciated.

2
  • What labels would you like? Commented Feb 13, 2017 at 20:35
  • Your code does not run - please provide the module imports you are using. Commented Feb 13, 2017 at 20:37

2 Answers 2

1

So I tried to make it simpler with a for loop, but have been unable to work out how to add labels to each plot inside the loop

from scipy import integrate from matplotlib import pyplot as plt MOm = 1.0 MOv = 0.0 COm = 0.3 COv = 0.7 z = np.arange(0.0,10,0.1) H0 = 70 Om = (1.0,0.3) Ov = (0.0,0.7) fig = plt.figure(1) for param1,param2 in zip(Om,Ov): def f(z): A = (5/2)*param1*(H0**2) H = H0 * np.sqrt( param1*((1+z)**3) + param2 ) return A * ((1+z)/(H**3)) def F(z): res = np.zeros_like(z) for i,val in enumerate(z): y,err = integrate.quad(f,val,np.inf) res[i] = y return res def D(z): return (H0 * np.sqrt( param1*((1+z)**3) + param2 )) * F(z) ## Now define labels as you need and labels as follows: plt.plot(z,D(z),label = 'Om: {}, Ov: {}'.format(param1,param2)) plt.legend() 

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

@Daniel You are welcome! Don't forget to also upvote any answers that you found useful! :)
1

You can create a label in the loop based on the two parameters using a predefined string which you format with the respective values.

label="Om {}, Ov {}".format(param1, param2) 

In total, that would give:

import numpy as np import scipy.integrate as integrate import matplotlib.pyplot as plt z = np.arange(0.0,10,0.1) MOm = 1.0 MOv = 0.0 COm = 0.3 COv = 0.7 H0 = 70 Om = (1.0,0.3) Ov = (0.0,0.7) plt.figure(figsize=(3.8,2.4)) for param1,param2 in zip(Om,Ov): def f(z): A = (5/2)*param1*(H0**2) H = H0 * np.sqrt( param1*((1+z)**3) + param2 ) return A * ((1+z)/(H**3)) def F(z): res = np.zeros_like(z) for i,val in enumerate(z): y,err = integrate.quad(f,val,np.inf) res[i] = y return res def D(z): return (H0 * np.sqrt( param1*((1+z)**3) + param2 )) * F(z) plt.plot(z,D(z), label="Om {}, Ov {}".format(param1, param2)) plt.legend() plt.show() 

enter image description here

3 Comments

With all due respect, it looks like you have posted the exact same code I did (with some extremely minor changes i.e. variable order and figsize) , 6 minutes after I posted it. You've literally lifted the label = 'Om: {}, Ov: {}'.format(param1,param2)) statement that I wrote. I know that this code segment is copied, because, in fact, you don't need any of the MOm MOv COm or COv variables to run this particular piece of code; I left them in by mistake - and yet at the time I write this comment, they are in your code. I may be mistaken, in which case I apologise; what is your take?
There are some standard ways of doing things, i.e. copy the code from the question, remove all that is obviously not needed, do the changes needed, write the answer, paste both back into the answer field and hit the post button. The fact that some of the variables which are not needed have survived only shows that we both did not pay too much attention. The question is what interest would I have in copying your code and why would I then bother making changes to it? If I had known that someone is working in parallel, posting a good answer to it, I'd better spent my time doing other stuff.
I suppose that makes sense, I think it was the length of time that initially caused me to question and just how similar the answer actually is. I must say though, your engaging as you have indicates that what I have said is probably not so. It looks like I'm starting to take this stuff too seriously - my apologies.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.