<a href="https://colab.research.google.com/github/aschelin/SimulacoesAGFE/blob/main/IntroGraficosPython.ipynb" target="_parent"></a>

# Gráficos no Python

> Material didático baseado no livro: *Python Programming and Numerical Methods - A Guide for Engineers and Scientists*.

A visualização de dados geralmente é a melhor maneira de transmitir ideias e informações importantes de engenharia e ciência, especialmente se as informações forem compostas por muitos, muitos números.  A capacidade de visualizar e plotar dados rapidamente e de muitas maneiras diferentes é um dos recursos mais poderosos do Python.

 Python tem várias funções gráficas que permitem a você exibir gráficos, superfícies, volumes, campos vetoriais, histogramas, animações e muitos outros gráficos de dados com eficiência.  Ao final deste tutorial, você deve estar familiarizado com os mais comuns e ter informações suficientes para explorar o resto.

Em Python, o matplotlib é o pacote mais importante para fazer um gráfico. Você pode dar uma olhada na *galeria do matplotlib* e ter uma noção do que pode ser feito lá.  Normalmente, a primeira coisa que precisamos para fazer um gráfico é importar o pacote matplotlib.  No notebook Jupyter, poderíamos mostrar a figura diretamente dentro do notebook e também ter as operações interativas como panorâmica, zoom in / out e assim por diante usando o comando mágico *%matplotlib notebook*.  Vamos ver alguns exemplos.


```python
import numpy as np
import matplotlib.pyplot as plt
%matplotlib notebook
```


```python
x = [0, 1, 2, 3] 
y = [0, 1, 4, 9]
plt.plot(x, y)
plt.show()
```

A função *plt.plot* fez o trabalho principal de plotar a figura, e a *plt.show()* está dizendo ao Python que terminamos a plotagem e para mostrar a figura.  

Vamos agora plotar a função:
\begin{equation}
f(x) = x^2 
\end{equation}
para
$-5\le x\le 5$.


```python
x = np.linspace(-5,5, 100)
plt.plot(x, x**2)
plt.show()
```

Para alterar o marcador ou a linha, você pode colocar um terceiro argumento de entrada no gráfico, que é uma string que especifica a cor e o estilo da linha a ser usado no gráfico.  Por exemplo, plot (x, y, 'ro') representará os elementos de x contra os elementos de y usando vermelho, r, círculos, 'o'.


```python
x = np.linspace(-5,5, 100)
plt.plot(x, x**2, 'ro')
plt.show()
```

Agora vamos plotar duas funções no mesmo gráfico. Considere novamente:
\begin{equation}
f(x) = x^2
\end{equation}
e
\begin{equation}
g(x) = x^3
\end{equation}
para $-5\le x \le 5$.




```python
x = np.linspace(-5,5,20)
plt.plot(x, x**2, 'ko')
plt.plot(x, x**3, 'r*')
plt.show()
```

O exemplo abaixo mostra como colocar os eixos:


```python
plt.figure(figsize = (10,6))

x = np.linspace(-5,5,20)
plt.plot(x, x**2, 'ko')
plt.plot(x, x**3, 'r*')
plt.title(f'Plote de polinômios {x[0]} to {x[-1]}')
plt.xlabel('X axis', fontsize = 18)
plt.ylabel('Y axis', fontsize = 18)
plt.show()
```

Podemos alterar qualquer parte da figura, como o tamanho do rótulo dos eixos xey, especificando um argumento de tamanho de fonte na função *plt.xlabel.*  Mas existem alguns estilos predefinidos que podemos usar para alterar o estilo automaticamente.  Aqui está a lista dos estilos.


```python
print(plt.style.available)
```

    ['Solarize_Light2', '_classic_test_patch', 'bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn', 'seaborn-bright', 'seaborn-colorblind', 'seaborn-dark', 'seaborn-dark-palette', 'seaborn-darkgrid', 'seaborn-deep', 'seaborn-muted', 'seaborn-notebook', 'seaborn-paper', 'seaborn-pastel', 'seaborn-poster', 'seaborn-talk', 'seaborn-ticks', 'seaborn-white', 'seaborn-whitegrid', 'tableau-colorblind10']



```python
plt.style.use('seaborn-poster')
```


```python
plt.figure(figsize = (10,6))

x = np.linspace(-5,5,20)
plt.plot(x, x**2, 'ko')
plt.plot(x, x**3, 'r*')
plt.title(f'Plot of Various Polynomials from {x[0]} to {x[-1]}')
plt.xlabel('X axis')
plt.ylabel('Y axis')
plt.show()
```

Você pode adicionar uma legenda ao seu gráfico usando a função *legend*.  E adicione um argumento de rótulo (*label*) na função plot.  A função de legenda também usa o argumento *loc* para indicar onde colocar a legenda, tente alterá-lo de 0 para 10.


```python
plt.figure(figsize = (10,6))

x = np.linspace(-5,5,20)
plt.plot(x, x**2, 'ko', label = 'quadratic')
plt.plot(x, x**3, 'r*', label = 'cubic')
plt.title(f'Plot of Various Polynomials from {x[0]} to {x[-1]}')
plt.xlabel('X axis')
plt.ylabel('Y axis')
plt.legend(loc = 2)
plt.show()
```

Você pode personalizar ainda mais a aparência de seu gráfico alterando os limites de cada eixo usando a função *xlim* ou *ylim*.  Além disso, você pode usar a função de *grid* para ativar a grade da figura.




```python
plt.figure(figsize = (10,6))

x = np.linspace(-5,5,100)
plt.plot(x, x**2, 'ko', label = 'quadratic')
plt.plot(x, x**3, 'r*', label = 'cubic')
plt.title(f'Plot of Various Polynomials from {x[0]} to {x[-1]}')
plt.xlabel('X axis')
plt.ylabel('Y axis')
plt.legend(loc = 2)
plt.xlim(-6.6)
plt.ylim(-10,10)
plt.grid()
plt.show()
```

Podemos criar uma tabela de gráficos em uma única figura usando a função *subplot*.  A função de subplot recebe três entradas: o número de linhas de plotagens, o número de colunas de plotagens e para as quais todas as chamadas para funções de plotagem devem ser plotadas.  Você pode mover para uma subtrama diferente chamando a subtrama novamente com uma entrada diferente para o local do gráfico.

Existem várias outras funções de plotagem que representam os dados x versus y.  Alguns deles são *scatter, bar, loglog, semilogx e semilogy*.  Dispersão (*scatter*) funciona exatamente da mesma forma que o gráfico, exceto que o padrão é de círculos vermelhos (ou seja, o gráfico (x, y, 'ro') é equivalente a dispersão (x, y)).  A função de barra (*bar*) plota barras centradas em x com altura y.  As funções *loglog, semilogx e semilogy* representam os dados em x e y com os eixos em uma escala logarítmica, o eixo x em uma escala logarítmica e o eixo y em uma escala linear e o eixo y em uma escala logarítmica  e o eixo x em uma escala linear, respectivamente.


```python
x = np.arange(11)
y = x**2

plt.figure(figsize = (14, 8))

plt.subplot(2, 3, 1)
plt.plot(x,y)
plt.title('Plot')
plt.xlabel('X')
plt.ylabel('Y')
plt.grid()

plt.subplot(2, 3, 2)
plt.scatter(x,y)
plt.title('Scatter')
plt.xlabel('X')
plt.ylabel('Y')
plt.grid()

plt.subplot(2, 3, 3)
plt.bar(x,y)
plt.title('Bar')
plt.xlabel('X')
plt.ylabel('Y')
plt.grid()

plt.subplot(2, 3, 4)
plt.loglog(x,y)
plt.title('Loglog')
plt.xlabel('X')
plt.ylabel('Y')
plt.grid(which='both')

plt.subplot(2, 3, 5)
plt.semilogx(x,y)
plt.title('Semilogx')
plt.xlabel('X')
plt.ylabel('Y')
plt.grid(which='both')

plt.subplot(2, 3, 6)
plt.semilogy(x,y)
plt.title('Semilogy')
plt.xlabel('X')
plt.ylabel('Y')
plt.grid()

plt.tight_layout()

plt.show()
```

Podemos ver que no final do nosso gráfico, usamos *plt.tight_layout* para fazer com que as sub-figuras não se sobreponham.


```python

```

Finalmente, existem outras funções para traçar dados em 2D.  A função de barra de erro plota dados x versus y, mas com barras de erro para cada elemento.  A função polar plota $\theta$ versus r em vez de x versus y.  A  A função hist faz um histograma de um conjunto de dados;  boxplot fornece um resumo estatístico de um conjunto de dados;  e torta faz um gráfico de pizza.  O uso dessas funções é deixado para sua exploração.  Lembre-se de verificar os exemplos na galeria matplotlib.

## Salvando as figuras

Se você deseja salvar as figuras em um formato específico, como pdf, jpeg, png e assim por diante, use a função *plt.savefig*.


```python
plt.figure(figsize = (8,6))
plt.plot(x,y)
plt.xlabel('X')
plt.ylabel('Y')
plt.savefig('image.pdf')
```

## Gráficos em 3D

Para plotar figuras 3D usando o  matplotlib, precisamos importar o kit de ferramentas *mplot3d*, que adiciona recursos de plotagem 3D simples ao matplotlib.


```python
from mpl_toolkits import mplot3d
import matplotlib.pyplot as plt
plt.style.use('seaborn-poster')
```


```python
fig = plt.figure(figsize = (10,10))
ax = plt.axes(projection='3d')
plt.show()
```

O ax = *plt.axes(projection = ’3d’)* criou um objeto de eixos 3D e, para adicionar dados a ele, usamos a função *plot3D*.  Podemos mudar o título, definir os rótulos x, y, z para o gráfico também.


```python

```

Considere que o conjunto de dados parametrizado onde $t$ é um vetor de $0$ a $10\pi$ com um passo $\pi/ 50$ e  $x = \sin (t)$ e $y = \cos (t)$.  

Faremos um gráfico tridimensional do conjunto de dados (x, y, t) usando *plot3*.  Vamos ativar a grade, tornar os eixos iguais e colocar rótulos de de eixos e um título.  


```python
%matplotlib inline
```


```python
fig = plt.figure(figsize = (8,8))
ax = plt.axes(projection='3d')
ax.grid()
t = np.arange(0, 10*np.pi, np.pi/50)
x = np.sin(t)
y = np.cos(t)

ax.plot3D(x, y, t)
ax.set_title('3D Parametric Plot')

# Set axes label
ax.set_xlabel('x', labelpad=20)
ax.set_ylabel('y', labelpad=20)
ax.set_zlabel('t', labelpad=20)

plt.show()
```


```python
x = np.random.random(50)
y = np.random.random(50)
z = np.random.random(50)

fig = plt.figure(figsize = (10,10))
ax = plt.axes(projection='3d')
ax.grid()

ax.scatter(x, y, z, c = 'r', s = 50)
ax.set_title('3D Scatter Plot')

# Set axes label
ax.set_xlabel('x', labelpad=20)
ax.set_ylabel('y', labelpad=20)
ax.set_zlabel('z', labelpad=20)

plt.show()
```


```python

```

Agora vamos fazer um gráfico de superfície em vez de um gráfico de linha ao plotar em três dimensões.  Na plotagem de superfície tridimensional, desejamos fazer um gráfico de alguma relação $f(x, y)$.  Na plotagem de superfície, todos os pares $(x, y)$ devem ser fornecidos.  

Isso não é fácil de fazer usando vetores.  Portanto, na plotagem de superfície, a primeira estrutura de dados que você deve criar é chamada de malha (*meshgrid*).  

Dadas listas/ matrizes de valores x e y, uma malha é uma lista de todas as combinações possíveis de x e y.  Em Python, a malha é fornecida como duas matrizes X e Y, onde X (i,j) e Y (i,j) definem os pares (x,y) possíveis.  

Uma terceira matriz, Z, pode então ser criada de modo que Z (i,j) = f (X (i,j),Y (i,j)).  Uma malha pode ser criada usando a função *np.meshgrid*.  A função *meshgrid* possui as entradas x e y, que são listas contendo o conjunto de dados independente.  


```python
x = [1, 2, 3, 4]
y = [3, 4, 5]

X, Y = np.meshgrid(x, y)
print(X)
```

    [[1 2 3 4]
     [1 2 3 4]
     [1 2 3 4]]



```python
print(Y)
```

    [[3 3 3 3]
     [4 4 4 4]
     [5 5 5 5]]


A função para plotar as superfícies 3D é *plot_surface(X, Y, Z)*, onde X e Y são as matrizes de saída do *meshgrid*, e $𝑍 = f(X, Y)$ .  

Outras funções de plotagem de superfície comuns são *surf* e *contour*.


```python
fig = plt.figure(figsize = (12,10))
ax = plt.axes(projection='3d')

x = np.arange(-5, 5.1, 0.2)
y = np.arange(-5, 5.1, 0.2)

X, Y = np.meshgrid(x, y)
Z = np.sin(X)*np.cos(Y)

surf = ax.plot_surface(X, Y, Z, cmap = plt.cm.cividis)

# Set axes label
ax.set_xlabel('x', labelpad=20)
ax.set_ylabel('y', labelpad=20)
ax.set_zlabel('z', labelpad=20)

fig.colorbar(surf, shrink=0.5, aspect=8)

plt.show()
```

Podemos fazer subtramas de diferentes tramas 3D também.  Usamos a função add_subplot do objeto de figura que criamos para gerar os subplots para casos 3D.


```python
fig = plt.figure(figsize=(12,6))


ax = fig.add_subplot(1, 2, 1, projection='3d')
ax.plot_wireframe(X,Y,Z)
ax.set_title('Wireframe plot')

ax = fig.add_subplot(1, 2, 2, projection='3d')
ax.plot_surface(X,Y,Z)
ax.set_title('Surface plot')

plt.tight_layout()

plt.show()
```

## Filmes e animações

Uma animação é uma sequência de quadros estáticos, ou plotagens, que são exibidos em uma sucessão rápida o suficiente para criar a ilusão de movimento contínuo. Podemos criar animações em Python chamando uma função plot dentro de um *loop* (geralmente um *loop* de *for*).  As principais ferramentas para fazer animações em Python são as classes base *matplotlib.animation.Animation*, que fornece uma estrutura em torno da qual a funcionalidade da animação é construída.  Veja exemplo:


```python
import matplotlib.animation as manimation
```


```python
n = 1000
x = np.linspace(0, 6*np.pi, n)
y = np.sin(x)

# Defina a meta data para o filme
FFMpegWriter = manimation.writers['ffmpeg']
metadata = dict(title='Filme teste', artist='Matplotlib',
                comment='um ponto vermelho seguindo uma função seno')
writer = FFMpegWriter(fps=15, metadata=metadata)

# Initialize the movie
fig = plt.figure()

# plot the sine wave line
sine_line, = plt.plot(x, y, 'b')
red_circle, = plt.plot([], [], 'ro', markersize = 10)
plt.xlabel('x')
plt.ylabel('sin(x)')

# Update the frames for the movie
with writer.saving(fig, "writer_test.mp4", 100):
    for i in range(n):
        x0 = x[i]
        y0 = y[i]
        red_circle.set_data(x0, y0)
        writer.grab_frame()
```

O código nesta célula, é apenas para permitir que você exiba os filmes que você gerou acima no Jupyter:


```python
from IPython.display import HTML

HTML("""
<div align="middle">
</div>""")
```





<div align="middle">
</div>



Antes de fazer um filme, é melhor preparar os 3 itens a seguir primeiro:



1.  Definir os metadados para o filme
2.  Decidir o que não precisa mudar no background.
3.  Decidir os objetos que precisam ser alterados em cada quadro do filme


Uma vez que os itens acima são determinados, fazer o filme em Python é relativamente fácil, precisamos apenas de 3 etapas:



1.  Definir os metadados para o filme
2.  Inicializar a figura de fundo do filme
3.  Atualizar os frames do filme

 No exemplo acima, podemos ver claramente o código relacionado às 3 etapas.

**Defindo os metadados do filme:**

Neste bloco de código, dizemos ao Python que começaremos a criar um roteirista de filme e daremos o título, artista, comentário a ele.  Além disso, também informamos ao Python que a taxa dos quadros no filme, ou seja, fps = 15, o que significa que exibimos 15 quadros consecutivos em 1 segundo (fps significa quadros por segundo).


```python
FFMpegWriter = manimation.writers['ffmpeg']
metadata = dict(title='Movie Test', artist='Matplotlib',
                comment='a red circle following a blue sine wave')
writer = FFMpegWriter(fps=15, metadata=metadata)
```

**Inicializando o background do filme:**

Aqui, começamos a fazer a inicialização da figura de fundo do filme.  O motivo pelo qual o chamamos de figura de fundo é que as coisas que plotamos aqui não mudarão durante o filme; neste exemplo, a curva de onda senoidal não mudará.  Ao mesmo tempo, traçamos um ponto vermelho vazio (que não aparecerá na figura).  Ele serve como um marcador de posição para as coisas que mudarão posteriormente no filme, isso é equivalente a dizer ao Python que teremos um ponto vermelho que depois atualizarei a localização do ponto.  Uma vez que os rótulos dos eixos xey também não mudarão, portanto, nós os plotamos aqui.


```python
fig = plt.figure()

# plot the sine wave line
sine_line, = plt.plot(x, y, 'b')
red_circle, = plt.plot([], [], 'ro', markersize = 10)
plt.xlabel('x')
plt.ylabel('sin(x)')
```

**Atualizando os frames do filme:**


```python
with writer.saving(fig, "writer_test.mp4", 100):
    for i in range(n):
        x0 = x[i]
        y0 = y[i]
        red_circle.set_data(x0, y0)
        writer.grab_frame()
```


```python

```

Neste bloco de código, especificamos o nome do arquivo de saída, formato e resolução da figura (dpi - pontos por polegada), neste caso, queremos que o arquivo de saída tenha um nome 'writer_test' com formato 'mp4',  e queremos o dpi da figura 100. Então, estamos entrando na parte central da produção do filme - atualizar a figura.  Usamos um loop for para atualizar a figura e, em cada loop, alteramos a localização (localização x, y) do círculo vermelho.  A função writer.grab_frame irá capturar essa mudança em cada quadro e exibi-la com base nos fps que definimos.

 Este é todo o processo de fazer este filme.

 Existem muitos exemplos de filmes no tutorial de filmes matplotlib, dê uma olhada e execute alguns dos exemplos para obter uma melhor compreensão de como fazer filmes em Python.


```python

```

4ed74fac660a920e1487c4db7d142e8190c8e78e
ipynb
Jupyter Notebook
IntroGraficosPython.ipynb
aschelin/SimulacoesAGFE
5294771ff8bf85a1129611bd3406780ef64ac75a
MIT
IntroGraficosPython.ipynb
aschelin/SimulacoesAGFE
5294771ff8bf85a1129611bd3406780ef64ac75a
MIT
IntroGraficosPython.ipynb
aschelin/SimulacoesAGFE
5294771ff8bf85a1129611bd3406780ef64ac75a
MIT
Qwen/Qwen-72B
1. YES
2. YES