import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

"""
Explanation: Matplotlib
Matplotlib is a popular Python library for graphical plotting. It works well with NumPy and Pandas. The <a href="https://matplotlib.org/gallery.html">gallery on Matplotlib's website</a> shows what kinds of plotting that it can perform. There is also a good <a href="http://www.labri.fr/perso/nrougier/teaching/matplotlib/">reference site</a> on the web.
End of explanation
"""


%matplotlib inline

# Generate data
x = np.linspace(0, 5, 11)
y = x ** 2

figure = plt.figure()
axes = figure.add_axes([.1, .1, .8, .8])
axes.plot(x, y)
axes.set_xlabel('X Label')
axes.set_ylabel('Y Label')
axes.set_title('Title')

# Generate data for a sine curve between 0 and 4*pi 
sin_x = np.linspace(0, 4*np.pi, 100)
sin_y = np.sin(sin_x) 

fig = plt.figure(figsize=(8,4))
ax = fig.add_axes([0, 0, 1, 1])
ax.set_xlim(0, 4*np.pi) # 
ax.set_ylim(-1.5, 1.5)
ax.plot(sin_x, sin_y, 'g')

"""
Explanation: To show plots in Jupyter Notebook, we need to execute %matplotlib inline. If we use other editors, we need to run plt.show() at the end to have our plot show up in a window.
End of explanation
"""


figure = plt.figure()
axes1 = figure.add_axes([0, 0, 1, 1])
axes1.set_facecolor('#d1ffb8')
axes1.plot(x, y, 'g.--')

axes2 = figure.add_axes([1.1, 0, 1, 1])
axes2.set_facecolor('#a6ddff')
axes2.plot(y, x, 'b*--')

"""
Explanation: Multiple Axes
End of explanation
"""


# Create an empty canvas with two subplots
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(15,4))
axes[0].plot(x, y, 'g')
axes[1].plot(y, x, 'b')

"""
Explanation: Automatic Axis Manager
Instead of creating a figure and calling add_axes(), we can use the subplots() method. It acts like an automatic axis manager.
End of explanation
"""


fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2)
for ax in [ax1, ax2, ax3, ax4]:
    ax.plot(x, y, 'g')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_title('title')

fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2)
for ax in [ax1, ax2, ax3, ax4]:
    ax.plot(x, y, 'g')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_title('title')
plt.tight_layout()

fig, axes = plt.subplots(nrows=2, ncols=2)
i = 0
for outer in axes:
    for ax in outer:
        i += 1
        ax.plot(x, y, 'g')
        ax.set_xlabel('x')
        ax.set_ylabel('y')
        ax.set_title('Axes No.{}'.format(i))
plt.tight_layout()

"""
Explanation: Overlapping Figures
A common issue with matplolib is overlapping subplots or figures. The method plt.tight_layout() automatically adjusts subplot parameters so that the subplot fits in to the figure canvas. This avoids overlapping content. This is an experimental feature and may not work for some cases. It only checks the extents of ticklabels, axis labels, and titles. For more information read the <a href="https://matplotlib.org/users/tight_layout_guide.html">Tight Layout guide</a>.
End of explanation
"""


fig, ax = plt.subplots(figsize=(12,6))

ax.plot(x, x**2, label='Squared', color='purple', linewidth=2, linestyle='-.', marker='o')
ax.plot(x, x**3, label='Cubed', color='green', marker='x', markersize=12)

# Use loc=0 to let Matplotlib determine the best location
ax.legend(loc=10) 

"""
Explanation: Colours, Markers and Legends
End of explanation
"""


fig = plt.figure()
ax1 = fig.add_axes([0, 0, 1, 1])
ax2 = ax1.twinx() #  Note that ax2 shares the x-axis with ax1
x2 = np.linspace(0., 10., 100)

ax1.set_ylabel('Density (cgs)', color='red')
ax2.set_ylabel('Temperature (K)', color='blue')
ax1.set_xlabel('Time (s)')

ax1.plot(x2, x2 ** 2, 'b-')
ax2.plot(x2, 1000 / (x2 + 1), 'r-')


"""
Explanation: Twin axes
Let two or more plots share the same x-axis using twinx() or the same y-axis using twiny().
End of explanation
"""


plt.scatter(x,y)

from random import sample
data = sample(range(1, 1000), 100)
plt.hist(data)

data = [np.random.normal(0, std, 100) for std in range(1, 4)]
plt.boxplot(data, vert=True, patch_artist=True);   

"""
Explanation: Plot Types
End of explanation
"""


