# Source on numpy data types: Johnson, J. Python Numpy Tutorial (with
# Jupyter and Colab). CS231n Convolutional Neural Networks for Visual
# Recognition. https://cs231n.github.io/python-numpy-tutorial/ (accessed
# September 4, 2021).

from matplotlib import pyplot
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from numpy import array
# We expect Concentration to vary with the exponential of Resistance.
# Source: Cai, H.; Lee T.M.; Hsing, I. Label-free protein recognition
# using an aptamer-based impedance measurement assay. Sensors and
# Actuators B: Chemical. 2006, 114, 433-437. DOI:
# 10.1016/j.snb.2005.06.017

# Import the exponential function e^x
from numpy import exp

# Dummy data for Resistance (generated by hand, which is not standard
# procedure):
xdata = array([5, 10, 15, 20, 25, 30, 35, 40, 45,
              50, 55, 60, 65, 70, 75, 80, 85])

# Corresponding Concentration (in sweat) dummy data points (same procedure):
ydata = array([1, 20, 39, 60, 76, 91, 103, 101, 100,
              102, 108, 106, 120, 151, 160, 180, 230])


# Source: kennytm, 2010. How to do exponential and logarithmic curve
# fitting in Python? I found only polynomial fitting. stack overflow.
# https://stackoverflow.com/questions/3433486/how-to-do-exponential-and-logarithmic-curve-fitting-in-python-i-found-only-poly
# (accessed September 4, 2021).

# a, b, c, and d are parameters (constants) to be determined, t is
# Resistance, and a + b*log(t) is Concentration
# p0 is our initial guesses for a, b, c, and d, respectively.
# We don't use covariance, just storing it because curve_fit yields two
# outputs.
params, covariance = curve_fit(
    lambda t, a, b, c, d: a + b * exp(c * t + d), xdata, ydata, p0=(0, 0.5, 0.0005, 0))

print(f'a, b, c, and d: {params}')
# [-1.54585335e+02  6.45104247e+00  8.36850408e-03  3.28891975e+00]
print(
    f'Equation predicting Sweat Concentration (y) from Resistance (x): {params[0]} + {params[1]}e^({params[2]}x + {params[3]})')

# Terrible fit because this dummy data is not very exponential, but the
# real experimental data we collect likely will be.


font1={'family':'serif','color':'#6ccfe2'}

#source on how to specify colors: https://matplotlib.org/stable/tutorials/colors/colors.html#sphx-glr-tutorials-colors-colors-py
# Source for hexidecimal code of color: https://www.color-hex.com/color/6ccfe2

# Graphs the dummy data points themselves
pyplot.scatter(xdata, ydata, label='dummy data',color='#929292') # Source on formatting matplotlib: https://towardsdatascience.com/all-your-matplotlib-questions-answered-420dd95cb4ff

# Graphs the best fit curve
plt.plot(xdata, params[0]+params[1]*exp(params[2] * xdata + params[3]), label='best fit curve',color='#6ccfe2',linestyle='--');
plt.legend();
plt.ylabel('Sweat Concentration (pg/mL)', fontsize = 10); #for y label
plt.xlabel('Resistance (ohms)', fontsize = 10); #for x label
plt.title('Electrical to Concentration relationship on dummy data',fontdict=font1,fontsize=15); #source: https://www.w3schools.com/python/matplotlib_labels.asp

# Source: Munir, 2016. Matplotlib plots aren't shown when running file
# from bash terminal. stack overflow.
# https://stackoverflow.com/questions/36269746/matplotlib-plots-arent-shown-when-running-file-from-bash-terminal
# (accessed September 9, 2021).
plt.show()
