#-----------------------------------------------------------
# Lecture 8 -- File IO and Plotting
#-----------------------------------------------------------
# additional references:
# * Numpy savetxt: https://docs.scipy.org/doc/numpy/reference/generated/numpy.savetxt.html
# * Numpy loadtxt: https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.loadtxt.html
# * Matplotlib documentation -- https://matplotlib.org/contents.html
# * Introductory matplotlib tutorial -- https://matplotlib.org/tutorials/introductory/pyplot.html#sphx-glr-tutorials-introductory-pyplot-py
# * 10 rules for better figures -- http://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1003833
# * matplotlib.pyplot.plot: https://matplotlib.org/api/_as_gen/matplotlib.pyplot.plot.html
# * Many examples! -- https://matplotlib.org/gallery/index.html
# * More about matplotlib formatting options -- https://matplotlib.org/api/_as_gen/matplotlib.pyplot.plot.html
# * More about global figure options (rcParams) -- https://matplotlib.org/devdocs/api/_as_gen/matplotlib.pyplot.rc.html

import numpy as np

#%%
#-----------------------------------------------------------
# A. Reading text files using Numpy
#-----------------------------------------------------------
#
# You can read in a data from a text file using the function:
#   np.loadtxt( <fileName>, <delimiter> )
# 
# Comments:
# * <filename> is a string of a file in your local directory
# * You can navigate to a directory in Spyder using the Folder icon in the 
#   top right corner.
# * <delimiter> is optional. The default value is any whitespace.
# * There are even more options. See the online documentation

mydata = np.loadtxt("pipe_data.csv", delimiter=',')
print(mydata)
print(mydata.shape)

# ----------
# Practice 
# ----------
# Load the file "rate_data.csv" that you saved using Excel
# ** Hint use the argument: skiprows=1 to skip the text header


#%%
#-----------------------------------------------------------
# B. Writing text files using Numpy
#-----------------------------------------------------------
#
# Text files can be written using the function:
#   np.savetxt( <filename>, <data>, <fmt>, <delimeter>)
# 
# Comments:
# * <filename> must a string. It will save the file in the local directory.
# * <data> must be a variable or numpy array (i.e. vector or matrix)
# * <fmt> is optional. "%.18e" is the default. See online ref for more about this.
# * <delimeter> is optional. The default value is a space:' '.
# * There are even more options. See the online documentation.

t = np.linspace(0, 5, 201) # t (min)
np.savetxt("t.dat", t)

#%%
# Two or more arrays can be combined using np.vstack (an array function 
# in numpy) and written to the same file.
#
# * Use the np.vstack function to make a 2-D array out of this data.
# * This makes a matrix with a column of t and a column of c.
# * Write this data to a text file using np.savetxt

t  = np.linspace(0,1,10)        
c = 4*np.exp(-t/1.2)*( 1 + 0.35*np.sin(np.pi*t) ) # c (mM)

data = np.vstack([t, c]).T # .T is a transpose
print("The rows and cols of data are", np.shape(data))

np.savetxt("rate_data.dat", data)

# ----------
# Practice 
# ----------
# Save x and y to a file comma-delimited called "Gaussian.csv"

x = np.linspace(-3, 3, 201)
y = 1./np.sqrt(2*np.pi) * np.exp(-x**2/2)

#%%
#-----------------------------------------------------------
# C. Plotting using the matplotlib module
#-----------------------------------------------------------
#
# Matplotlib is a module for making easy, professional quality plots and
# figures. It is very powerful and has *many* options.  One can make much nicer
# figures using matplotlib than using Excel.  It is also much easier to save
# figures to different formats using matplotlib.

import matplotlib.pyplot as plt

# ** Menu option to get interactive plots **
# Tools -> Preferences -> IPython console -> Graphics (tab) -> 
# Graphics Backend, Backend: (drop down menu) -> Automatic
# * Then restart Spyder
# * Default option is "Inline" -> appears in ipython console
# OR can use ipython's "magic" command
#   from IPython import get_ipython
# and either one:
#   get_ipython().magic('matplotlib inline') # == %matplotlib inline
#   get_ipython().magic('matplotlib auto') # == %matplotlib auto

# A basic plot can be produced by calling the plot( <xdata>, <ydata> ) function

x = np.linspace(0,6,51)
y = np.exp(-x)*np.sin(4*x)
plt.plot(x,y)

#%%
# Some basic formatting
# * linestyle: '-', '--', ':', '-.'
# * symbols: 'o', 'x', 's', etc.
# * colors: 'r', 'g', 'b', 'm', etc.
# * labels, title and legend

plt.plot(x,y, 'ko-')                # linestyle, symbols, colors
plt.xlabel('The x-axis label')
plt.ylabel('The y-axis label')
plt.title('Some title')
plt.legend(['my curve'])

# ----------
# Practice 
# ----------
# Load rate_data.csv and plot t vs c.
# Label the x- and y-axes as 't (min)' and 'c (mM)' respectively.

#%%
#-----------------------------------------------------------
# D. Examples using more formatting Options
#-----------------------------------------------------------
#
# * Multiple curves on the same plot
# * xlim, ylim -- limits of plot
# * xscale, yscale -- 'log' or 'linear'

x = np.logspace(-2,4,51)
y1 = x**(-3)
y2 = x**(-0.2)

plt.figure() # creates a new figure if one is already open
plt.plot(x, y1, 'r--')
plt.plot(x, y2, 'bx')

plt.xscale('log')
plt.yscale('log')

plt.xlim([1e-2,1e4])
plt.ylim([1e-2,1e4])
plt.xlabel('x') 
plt.ylabel('y')                           
plt.legend(['curve 1', 'curve2']);  
plt.title('log-log plot')
plt.show() # forces python to show plot here, instead of waiting until end

#%%
# * Multiple curves on the same plot
# * plot options: color, linewidth, markersize
# * global font size: rc() (also has other global parameters)
# * legend options: frameon, location, fontsize
# * save to file

x = np.linspace(0,10,51)
y1 = 2*np.exp(-x/2)
y2 = 2*np.exp(-x/2)*np.cos(2*x)

plt.figure()
plt.rc("font", size=10) # Set all font sizes
plt.rc('figure', figsize=(8, 6)) # size in inches

plt.plot(x, y1, linestyle='--', color='green', linewidth=3)
plt.plot(x, y2, linestyle='-', marker='s' , color='blue',  markersize=2)

plt.xlim([0,10])
plt.ylim([-2,2])
plt.xlabel(r'With Symbols: $\alpha_{s}\beta^{s}$', fontsize=20) # r'' is a string literal
plt.ylabel('some label', fontsize=20)                           
plt.legend(['curve 1', 'curve2'], fontsize=16, frameon=False, loc='upper right')

plt.tight_layout() # fixes spacing issues around edge of the box

# be careful of working directory (make explicit or 
# use toolbar to navigate to local directory)
plt.savefig('saved_figure.png')

