# -*- coding: utf-8 -*-
"""
Created on Fri Sep 25 14:09:12 2020

@author: jbobowsk
"""

# This tutorial demonstrates how to create log-log scale plots and semilog
# (log-linear & linear-log) plots.

import math
import numpy as np
import matplotlib.pyplot as plt

# Log-log plots are created using the 'loglog' command.  It has all the
# same formating options as 'plot' which are discussed in the basic_plots.m
# script.

# First, we define a function to plot.  This function is the output of a
# simple low-pass RC filter.
def lowpass(f, f0):
    return 1/np.sqrt(1 + (f/f0)**2)

# Next, we generate a logarithmically-spaced array of values using 
# 'np.logspace(a, b, n)' where 10^a is the first entry in the array and
# 10^b is the last entry.  n is the number of elements in the array.
ff = np.array(np.logspace(0, 5, 1000))

# Here's the first log-log plot.
f0 = 1e4
plt.loglog(ff, lowpass(ff, f0), 'k-', linewidth = 2.5)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Low-pass Filter')
plt.axis((10, 1e5, 0.1, 1.2))

# Let's add the curve from a second low-pass filter with
# a different cut-off frequency.
f0 = 1e3
plt.loglog(ff, lowpass(ff, f0), 'r--', linewidth = 1.5)
plt.legend((r'$f_0 = 10$ kHz', r'$f_0 = 1$ kHz'), loc = 'lower left', frameon = False)

# Semilog plots are created using 'plt.semilogx' and 'plt.semilogy'.  Here's
# plt.semilogx.
plt.figure()
f0 = 1e4
plt.semilogx(ff, lowpass(ff, f0), 'k-', linewidth = 2.5)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Low-pass Filter')
plt.axis((10, 1e5, 0.1, 1.2))

# Add another curve to the log-linear plot.
f0 = 1e3
plt.semilogx(ff, lowpass(ff, f0), 'r--', linewidth = 1.5)
plt.legend((r'$f_0 = 10$ kHz', r'$f_0 = 1$ kHz'), loc = 'lower left', frameon = False)

# Here's semilogy.
plt.figure()
f0 = 1e4
plt.semilogy(ff, lowpass(ff, f0), 'k-', linewidth = 2.5)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Low-pass Filter')
plt.axis((10, 1e5, 0.1, 1.2))

# Add another curve to the linear-log plot.
f0 = 1e3
plt.semilogy(ff, lowpass(ff, f0), 'r--', linewidth = 1.5)
plt.legend({r'$f_0 = 10$ kHz', r'$f_0 = 1$ kHz'}, loc = 'upper right', frameon = False)

# The easiest way that I've found to do plots with error bars on log scales
# is to use 'errorbar' (as shown in basic_plots.m) and then modify whatever
# axis you want to be on a log scale afterwards.  Below, 'set(gca, ...)' is
# used to change the x-axis to be on a log scale.
plt.figure()
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
y = [1.02, 4.3, 8.6, 16, 22, 34, 45, 60.2, 80.1, 96, 125, 144]
dy = [.3, .3, .5, 2, 2, 2, 4, 4, 6, 10, 20, 20]
formattedPlot = plt.errorbar(x, y, dy, fmt = 'ko', markersize = 6,\
    capsize = 5, linewidth = 1.5, markerfacecolor = 'y');
plt.xlabel('x-axis label', fontsize = 14, fontname = 'Times')
plt.ylabel('y-axis label', fontsize = 14, fontname = 'Times')
plt.xscale('log')
plt.axis((0.8, 15, 0, 180))

# Here's an error bar plot with the y-axis on a log scale.
plt.figure()
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
y = [1.02, 4.3, 8.6, 16, 22, 34, 45, 60.2, 80.1, 96, 125, 144]
dy = [.3, .3, .5, 2, 2, 2, 4, 4, 6, 10, 20, 20]
formattedPlot = plt.errorbar(x, y, dy, fmt = 'ko', markersize = 6,\
    capsize = 5, linewidth = 1.5, markerfacecolor = 'y');
plt.xlabel('x-axis label', fontsize = 14, fontname = 'Times')
plt.ylabel('y-axis label', fontsize = 14, fontname = 'Times')
plt.yscale('log')
plt.axis((0, 15, 0.4, 180))

# Here's an error bar plot with both axes on a log scale.
plt.figure()
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
y = [1.02, 4.3, 8.6, 16, 22, 34, 45, 60.2, 80.1, 96, 125, 144]
dy = [.3, .3, .5, 2, 2, 2, 4, 4, 6, 10, 20, 20]
formattedPlot = plt.errorbar(x, y, dy, fmt = 'ko', markersize = 6,\
    capsize = 5, linewidth = 1.5, markerfacecolor = 'y');
plt.xlabel('x-axis label', fontsize = 14, fontname = 'Times')
plt.ylabel('y-axis label', fontsize = 14, fontname = 'Times')
plt.xscale('log')
plt.yscale('log')
plt.axis((0.8, 15, 0.4, 180))

# Just for fun, we can add a line to this last plot.
# We just use plot and the axes will still be on log scales.
xx = np.array(np.logspace(-1, 2, 1000))
plt.plot(xx, xx**2, 'b-', linewidth = 1.5)