%matplotlib inline

import matplotlib.pyplot as plt

"""
Explanation: Aula 03 - Matplotlib
Objetivos

Criar gráficos 1-2D
Customizar gráficos
Criar funções para plots complexos
Apresentar Cartopy e criar mapas simples

http://www.labri.fr/perso/nrougier/teaching/matplotlib/matplotlib.html
Matplotlib é um pacote (ou módulo) Python usado pela comunidade científica
para produzir gráficos 2D.  Esse pacote suporta diversos formatos como PNG,
JEPG, PostScript/EPS, PDF e SVG.
Matplotlib traz um sub-pacote de conveniência chamado pyplot que, para manter
a consistência com usuários do matplotlib, deve sempre ser importado como plt:
End of explanation
"""


fig = plt.figure()

"""
Explanation: O coração de todos os gráficos é o objeto figure.  O objeto Figure
está no pode ser desenhado em qualquer formato de saída ou apenas a tela.
End of explanation
"""


ax = plt.axes()

"""
Explanation: Sozinho o objeto Figure não é interessante.  Temos que "desenhar" algo nele.
Os objetos de desenho do matplotlib são chamados de Artists.  De longe o
Artists mais útil é o Axes artist.  O Axes artist representa o
espaço dos dados (x, y) ou em caso de coordenadas polares (r, $\theta$).
Não há limite no número de Artists que podemos adicionar em uma figura.
Vamos ver um exemplo.
End of explanation
"""


ax = plt.axes()

line1 = ax.plot([0, 1, 2, 1.5], [3, 1, 2, 4])

"""
Explanation: A maior parte do tempo você vai trabalhar com o objeto Axes.  A documentação
é bem detalhada e recomendo a leitura, principalmente do método plot:

http://matplotlib.org/api/pyplot_summary.html
http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.plot
http://matplotlib.org/api/axes_api.html?#matplotlib.axes.Axes.plot
End of explanation
"""


import numpy as np

x = np.linspace(-180, 180, 60)
y = np.linspace(-90, 90, 30)
x2d, y2d = np.meshgrid(x, y)

data = np.cos(3 * np.deg2rad(x2d)) + np.sin(2 * np.deg2rad(y2d))

plt.contourf(x, y, data);

plt.imshow(data, extent=[-180, 180, -90, 90],
           interpolation='nearest', origin='lower');

plt.pcolormesh(x, y, data);

plt.scatter(x2d, y2d, c=data, s=15);

plt.bar(x, data.sum(axis=0), width=np.diff(x)[0]);

plt.plot(x, data.sum(axis=0),
         linestyle='--',
         marker='d',
         markersize=10,
         color='red');

"""
Explanation: Outros tipos de gráficos
End of explanation
"""


fig = plt.figure()
ax = plt.axes()
fig.subplots_adjust(top=0.8)

fig.suptitle(u'Título do "Figure"', fontsize=18, fontweight='bold')
ax.set_title(u'Título do "Axes', fontsize=16)
ax.set_xlabel('O Eixo X')
ax.set_ylabel('O Eixo Y $y=f(x)$', fontsize=16)
ax.text(0.5, 0.5, 'Texto centrado em (0.5, 0.5)\nin data coordinates.',
        horizontalalignment='center', fontsize=14);

x = np.linspace(-3, 7, 200)

plt.plot(x, 0.5*x**3 - 3*x**2, linewidth=2,
         label='$f(x)=0.5x^2-3x^2$')

plt.plot(x, 1.5*x**2 - 6*x, linewidth=2, linestyle='--',
         label='Gradiente de $f(x)$', )

plt.legend(loc='lower right')
plt.grid(True)

x = np.linspace(-180, 180, 60)
y = np.linspace(-90, 90, 30)
x2d, y2d = np.meshgrid(x, y)
data = np.cos(3 * np.deg2rad(x2d)) + np.sin(2 * np.deg2rad(y2d))

plt.contourf(x, y, data)
plt.colorbar(orientation='horizontal');

x = np.linspace(-3, 7, 200)
plt.plot(x, 0.5*x**3 - 3*x**2, linewidth=2)
plt.annotate('Local minimum',
             xy=(4, -18),
             xytext=(-2, -40), fontsize=15,
             arrowprops={'facecolor': 'black', 'frac': 0.3})
plt.grid(True)

plt.plot(range(10))

plt.savefig('simple.svg')

from IPython.display import SVG

SVG('./simple.svg')

"""
Explanation: Títulos, Legendas, colorbars e anotações
End of explanation
"""


import numpy as np
import numpy.ma as ma

data = np.loadtxt("./data/dados_pirata.csv", skiprows=1,
                  usecols=range(2, 16), delimiter=',')

data = ma.masked_less_equal(data, -9999)

plt.pcolormesh(np.flipud(data.T))
plt.colorbar();

fig, ax = plt.subplots(figsize=(12.5, 5))

cs = ax.pcolormesh(np.flipud(data.T))

fig.colorbar(cs);

z = [1, 10, 100, 120, 13, 140, 180, 20, 300, 40, 5, 500, 60, 80]

fig, ax = plt.subplots()
ax.plot(data[42, :], z, 'ko')
ax.invert_yaxis()

fig, ax = plt.subplots(figsize=(9, 3))

ax.plot(data[:, 0])

ax.set_xlabel("Tempo")
ax.set_ylabel("Temperatura")
ax.set_title(u"Série-temporal PIRATA");

def plot_ts(data):
    fig, ax = plt.subplots(figsize=(9, 3))

    ax.plot(data)
    ax.set_xlabel("Tempo")
    ax.set_ylabel("Temperatura")
    ax.set_title(u"Série-temporal PIRATA")

plot_ts(data)

from matplotlib import style

style.available

with style.context('dark_background'):
    plot_ts(data[:, 0])

with style.context('ggplot'):
    plot_ts(data[:, 0])

style.use('ggplot')

n, bins, pathes = plt.hist(data[0, :])

style.use('ggplot')

idx = 0
mask = data.mask[:, 0]

n, bins, pathes = plt.hist(data[:, 0].data[~mask], bins=10)

idx = 12

mask = data.mask[:, idx]

n = plt.hist(data[:, idx].data[~mask], bins=30)

def make_wave():
    twopi = 2 * np.pi
    n = 2
    A = 2
    w = twopi / 10
    k = twopi / 200
    phi = np.deg2rad(180)
    t = np.arange(0, 10 * n, 0.01)
    y = A * np.cos(w * t - k * 0 + phi)

    fig, ax = plt.subplots(figsize=(8, 4))
    ax.plot(t, y, linewidth='2', color='#006633')
    ax.set_frame_on(False)
    ax.axis([-0.1, 20.1, -3, 3])
    ax.get_xaxis().set_ticks([])
    ax.get_yaxis().set_ticks([])

    # Box.
    kw = dict(linestyle='--', color='grey', zorder=90)
    ax.axhline(y=2, xmin=0.15, xmax=0.85, **kw)
    ax.axhline(y=-2, xmin=0.15, xmax=0.85, **kw)
    ax.axvline(x=5, ymin=-0.15, ymax=1.85, **kw)
    ax.axvline(x=15, ymin=-0.15, ymax=1.85, **kw)

    # Zero line.
    _ = ax.annotate('', xy=(20, 0), xycoords='data',
                xytext=(0, 0), textcoords='data',
                arrowprops=dict(arrowstyle='->', color='black'))

    _ = ax.annotate(u'Espaço', xy=(20, 0), xycoords='data',
                xytext=(20, 0.05), textcoords='data', 
                va='bottom', ha='right', color='blue')

    _ = ax.annotate('Tempo', xy=(20, 0), xycoords='data',
                xytext=(20, -0.05), textcoords='data', 
                va='top', ha='right', color='red')

    # Arrow commom properties.
    arrowprops = dict(arrowstyle='<->', color='black')

    # Wave period (or length).
    _ = ax.annotate('', xy=(15, 2.5), xycoords='data',
                xytext=(5, 2.5), textcoords='data',
                arrowprops=arrowprops)

    _ = ax.annotate(u'Comprimento', xy=(10, 2.5), xycoords='data',
                xytext=(10, 2.55), textcoords='data', 
                va='bottom', ha='center', color='blue')

    _ = ax.annotate(u'Período', xy=(10, 2.5), xycoords='data',
                xytext=(10, 2.45), textcoords='data', 
                va='top', ha='center', color='red')

    # Amplitude.
    _ = ax.annotate('', xy=(5, 2), xycoords='data',
                xytext=(5, 0), textcoords='data',
                arrowprops=arrowprops)

    _ = ax.annotate('Amplitude', xy=(5, 1), xycoords='data',
                xytext=(4.9, 1), textcoords='data', 
                va='center', ha='right', rotation=90)

    # Height.
    ax.annotate('', xy=(15, 2), xycoords='data',
                xytext=(15, -2), textcoords='data',
                arrowprops=arrowprops)

    _ = ax.annotate('Altura', xy=(15, 1), xycoords='data',
                xytext=(14.9, 0.1), textcoords='data', 
                va='bottom', ha='right', rotation=90)

    # Angle.
    _ = ax.annotate('', xy=(15, 2), xycoords='data',
                xytext=(5, -2), textcoords='data',
                arrowprops=arrowprops)

    _ = ax.annotate(u'Inclinação', xy=(10, 0), xycoords='data',
                xytext=(10.5, 0.5), textcoords='data', 
                va='center', ha='center', rotation=35)

make_wave()

from matplotlib.dates import date2num


def stick_plot(time, u, v, **kw):
    width = kw.pop('width', 0.002)
    headwidth = kw.pop('headwidth', 0)
    headlength = kw.pop('headlength', 0)
    headaxislength = kw.pop('headaxislength', 0)
    angles = kw.pop('angles', 'uv')
    ax = kw.pop('ax', None)
    
    if angles != 'uv':
        raise AssertionError("Stickplot angles must be 'uv' so that"
                             "if *U*==*V* the angle of the arrow on"
                             "the plot is 45 degrees CCW from the *x*-axis.")

    time, u, v = map(np.asanyarray, (time, u, v))
    if not ax:
        fig, ax = plt.subplots()
    
    q = ax.quiver(date2num(time), [[0]*len(time)], u, v,
                  angles='uv', width=width, headwidth=headwidth,
                  headlength=headlength, headaxislength=headaxislength,
                  **kw)

    ax.axes.get_yaxis().set_visible(False)
    ax.xaxis_date()
    return q

def make_quiver():
    from datetime import datetime, timedelta

    x = np.arange(100, 110, 0.1)
    start = datetime.now()
    time = [start + timedelta(days=n) for n in range(len(x))]
    u, v = np.sin(x), np.cos(x)


    fig, ax = plt.subplots(figsize=(11, 2.75))

    q = stick_plot(time, u, v, ax=ax, width=0.002, color='green')

    ref = 1
    qk = ax.quiverkey(q, 0.1, 0.85, ref,
                      "%s N m$^{-2}$" % ref,
                      labelpos='N', coordinates='axes')

make_quiver()

from IPython.display import IFrame

url = "http://matplotlib.org/gallery.html"

IFrame(url, width=900, height=500)

"""
Explanation: Exemplo com dados reais
End of explanation
"""


!head -1 ./data/dados_pirata.csv

fig, (ax0, ax1) = plt.subplots(ncols=2, sharey=True)

Z = [1, 10, 100, 120, 13, 140, 180, 20, 300, 40, 5, 500, 60, 80]

ax0.plot(data[42, :], Z, 'o')
ax1.plot(data[342, :], Z, 'o')

ax0.invert_yaxis()

!head -1 ./data/dados_pirata.csv

fig, (ax0, ax1) = plt.subplots(nrows=2, sharex=True)

ax0.plot(data[:, 0])
ax1.plot(data[:, -3]);

fig, ax = plt.subplots()

Z = [1, 10, 100, 120, 13, 140, 180, 20, 300, 40, 5, 500, 60, 80]

ax.plot(data.mean(axis=0), Z, 'o')

ax.invert_yaxis()

"""
Explanation: Exercícios usando os dados da boia Piratas


1) Plotar dois perfis verticais lado a lado e compartilhando o eixo y.  Dica: use o método plt.subplots()


2) Plotar as séries temporais, superfície e fundo, alinhadas verticalmente  e compartilhando o eixo x


3) Perfil vertical médio para todo o período
End of explanation
"""


url = "https://ocefpaf.github.io/python4oceanographers/blog/2013/12/09/zoom/"

IFrame(url, width=900, height=500)

"""
Explanation: Perguntas

1) Como fazer para realizar operações (médias, max, min, etc) apenas nos ano (ou meses) desses dados?
2) Como ordenar o eixo z para podermos ligar as linhas?
End of explanation
"""


