Having problems to plot this equation, giving wrong plot - numpy

I'm trying to plot a radioisotope's power output by time. For this, I've found the following equation:
without the exponential at the end it works but I need the difference by time so I need to use it but I can't make that part work.
This is my code:
import matplotlib.pyplot as plt
import numpy as np
import math
ln2=0.693
avon=6.02214076*(10**23)
mevj=1.6*(10**(-13))
t = np.array(range(50))
co60 = (((ln2)/(5.27*365*24*3600))*((avon)*mevj*2.505/60))/(2.718**((ln2)/(5.27*365*24*3600)*(t))))
plt.plot(t, co60, label='co60')
This gives a wrong output. I can't get an exponential plot. I used 2.718 for e since when I use math.exp it gives errors. The correct output must be like the black line.
I think I'm having troubles with using the mathematical dynamics of python and couldn't interpret the equation correctly. Could you help?
Thanks.

Related

A mysterious behavior of matplotlib - plot

I intended to plot a trend of daily BTC prices, which is recorded as a csv file, consisting of a sequence of 3892 numbers.
Being a csv file, I could use microsoft excel to plot the trend.
It looks like this;
Meanwhile, I attempted to do the same thing using pandas and matplotlib in a jupyter notebook, which doesn't look good;
What's wrong with my implementation?
One more thing is the implementing time ; it takes a quite a while, like one or two minute.
This is not the case when I put a code and implement like this ;
plt.plot(list(range(1000)),list(range(1000)))
Here is the full code for my attempt.
import pandas as pd
from matplotlib import pyplot as plt
df=pd.read_csv('BTC_inv_daily.csv')
Close=df['Close'].tolist()
N=len(Close)
plt.plot(list(range(N)),Close)
plt.show()

Numpy gradient with non uniform spacing

I got something wrong going on :
import numpy as np
import matplotlib.pyplot as plt
x = np.concatenate((np.linspace(0,1,100),np.linspace(1,2,50)));
f = np.power(x,2);
df = 2*x;
Df = np.gradient(f,x);
plt.plot(x,df,'r', x,Df,'b');plt.show()
This is what I get :
Otherwise things work ok if using linearly spaced array and not using argument x.
Any suggestions?
I think this is because numpy versions before 1.13 expect the "x" argument to be the constant grid spacing (see https://docs.scipy.org/doc/numpy-1.11.0/reference/generated/numpy.gradient.html#numpy.gradient). Even though the earlier versions expect a scalar dx, they do not check for this, and the result is np.gradient(f) / x, which is a valid division. This is pretty annoying since code written for numpy 1.13 may run on earlier versions with incorrect output and no errors.

Basic axis malfuction in matplotlib

When plotting using matplotlib, I ran into an interesting issue where the y axis is scaled by a very inconvenient quantity. Here's a MWE that demonstrates the problem:
import numpy as np
import matplotlib.pyplot as plt
l = np.linspace(0.5,2,2**10)
a = (0.696*l**2)/(l**2 - 9896.2e-9**2)
plt.plot(l,a)
plt.show()
When I run this, I get a figure that looks like this picture
The y-axis clearly is scaled by a silly quantity even though the y data are all between 1 and 2.
This is similar to the question:
Axis numerical offset in matplotlib
I'm not satisfied with the answer to this question in that it makes no sense to my why I need to go the the convoluted process of changing axis settings when the data are between 1 and 2 (EDIT: between 0 and 1). Why does this happen? Why does matplotlib use such a bizarre scaling?
The data in the plot are all between 0.696000000017 and 0.696000000273. For such cases it makes sense to use some kind of offset.
If you don't want that, you can use you own formatter:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker
l = np.linspace(0.5,2,2**10)
a = (0.696*l**2)/(l**2 - 9896.2e-9**2)
plt.plot(l,a)
fmt = matplotlib.ticker.StrMethodFormatter("{x:.12f}")
plt.gca().yaxis.set_major_formatter(fmt)
plt.show()

Cubic spline interpolation drops out halfway

I am trying to make a cubic spline interpolation and for some reason, the interpolation drops off in the middle of it. It's very mysterious and I can't find any mention of similar occurrences anywhere online.
This is for my dissertation so I have excluded some labels etc. to keep it obscure intentionally, but all the relevant code is as follows. For context, this is an astronomy related plot.
from scipy.interpolate import CubicSpline
import numpy as np
import matplotlib.pyplot as plt
W = np.array([0.435,0.606,0.814,1.05,1.25,1.40,1.60])
sum_all = np.array([sum435,sum606,sum814,sum105,sum125,sum140,sum160])
sum_can = np.array([sumc435,sumc606,sumc814,sumc105,sumc125,sumc140,sumc160])
fall = CubicSpline(W,sum_all)
newallx=np.arange(0.435,1.6,0.001)
newally=fall(newallx)
fcan = CubicSpline(W,sum_can)
newcanx=np.arange(0.435,1.6,0.001)
newcany=fcan(newcanx)
#----plot
plt.plot(newallx,newally)
plt.plot(newcanx,newcany)
plt.plot(W,sum_all,marker='o',color='r',linestyle='')
plt.plot(W,sum_can,marker='o',color='b',linestyle='')
plt.yscale("log")
plt.ylabel("Flux S$_v$ [erg s$^-$$^1$ cm$^-$$^2$ Hz$^-$$^1$]")
plt.xlabel("Wavelength [n$\lambda$]")
plt.show()
The plot that I get from that comes out like this, with a clear gap in the interpolation:
And in case you are wondering, these are the values in the sum_all and sum_can arrays (I assume it doesn't matter, but just in case you want the numbers to plot it yourself):
sum_all:
[ 3.87282732e+32 8.79993191e+32 1.74866333e+33 1.59946687e+33
9.08556547e+33 6.70458731e+33 9.84832359e+33]
can_all:
[ 2.98381061e+28 1.26194810e+28 3.30328780e+28 2.90254609e+29
3.65117723e+29 3.46256846e+29 3.64483736e+29]
The gap happens between [0.606,1.26194810e+28] and [0.814,3.30328780e+28]. If I change the intervals from 0.001 to something higher, it's obvious that the plot doesn't actually break off but merely dips below 0 on the y-axis (but the plot is continuous). So why does it do that? Surely that's not a correct interpolation? Just looking with our eyes, that's clearly not a well-interpolated connection between those two points.
Any tips or comments would be extremely appreciated. Thank you so much in advance!
The reason for the breakdown can be better observed on a linear scale.
We see that the spline actually passes below 0, which is undefined on a log scale.
So I would suggest to first take the logarithm of the data, perform the spline interpolation on the logarithmically scaled data, and then scale back by the 10th power.
from scipy.interpolate import CubicSpline
import numpy as np
import matplotlib.pyplot as plt
W = np.array([0.435,0.606,0.814,1.05,1.25,1.40,1.60])
sum_all = np.array([ 3.87282732e+32, 8.79993191e+32, 1.74866333e+33, 1.59946687e+33,
9.08556547e+33, 6.70458731e+33, 9.84832359e+33])
sum_can = np.array([ 2.98381061e+28, 1.26194810e+28, 3.30328780e+28, 2.90254609e+29,
3.65117723e+29, 3.46256846e+29, 3.64483736e+29])
fall = CubicSpline(W,np.log10(sum_all))
newallx=np.arange(0.435,1.6,0.001)
newally=fall(newallx)
fcan = CubicSpline(W,np.log10(sum_can))
newcanx=np.arange(0.435,1.6,0.01)
newcany=fcan(newcanx)
plt.plot(newallx,10**newally)
plt.plot(newcanx,10**newcany)
plt.plot(W,sum_all,marker='o',color='r',linestyle='')
plt.plot(W,sum_can,marker='o',color='b',linestyle='')
plt.yscale("log")
plt.ylabel("Flux S$_v$ [erg s$^-$$^1$ cm$^-$$^2$ Hz$^-$$^1$]")
plt.xlabel("Wavelength [n$\lambda$]")
plt.show()

matplotlib tex renderer gives unexpected error

I am creating a scatter plot with color map based on some values and I am trying to make part of the x_axis label italic (inspired mostly by this post -> https://stackoverflow.com/a/8384685/1093485) but I am getting a LaTeX error that I can not explain myself, I would appreciate if anyone is able to explain what is going wrong with this chunk?
Minimum code required to reproduce problem here:
#! /usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
X = [1257.422648,1298.449197,1339.475746,1419.475471,1455.52309,1460.50202,1485.533655]
Y = [21.84637515,18.19617016,22.29456694,5.228978612,3.888695726,12.36598466,4.201838517]
Z = [44.02797944,9.758071204,21.58997772,64.53887544,53.09630431,8.461254471,291.4311435]
# Enable LaTeX style
rc('text',usetex=True)
# Plot the data
fig=plt.figure()
fig.patch.set_facecolor('white')
ax=fig.add_subplot(111)
s = ax.scatter(X,Y,c=np.log(Z))
ax.set_xlabel(r'Analyte \textit{m/z}')
ax.xaxis.labelpad = 7.5
cb = plt.colorbar(mappable=s,ax=ax)
plt.show()
Commenting the rc('text',usetex=True) causes the plot to show but obviously without italics. The whole traceback is rather large but seems to revolve around this part (if I read it correctly):
RuntimeError: LaTeX was not able to process the following string:
'$1450$'
Anyone have a suggestion on what to do to isolate the problem?