# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: percent
#       format_version: '1.3'
#       jupytext_version: 1.14.0
#   kernelspec:
#     display_name: Python [conda env:CompWS22] *
#     language: python
#     name: conda-env-CompWS22-py
# ---

# %% [markdown] slideshow={"slide_type": "slide"}
# # NumPy und Matplotlib

# %%
import numpy as np

# %% [markdown] slideshow={"slide_type": "slide"}
# ## Universal functions (ufunc)
#
# Die universellen Funktionen aus NumPy (sin, cos, tan, arcsin, arccos, sinh, cosh, arcsinh, ... exp, log, log2, log10, sqrt, ...) wirken elementweise, wenn sie auf NumPy Arrays angewandt werden. https://numpy.org/doc/stable/reference/ufuncs.html

# %% slideshow={"slide_type": "-"}
x = np.linspace(0, 5*np.pi, 10) # 10 äquidistante Zahlen zwischen 0 und 5 pi
x, np.sin(x)

# %%
np.info(np.arctan)

# %% slideshow={"slide_type": "slide"}
# %%timeit
y = np.sin(x)

# %% slideshow={"slide_type": "fragment"}
# %%timeit
l = []
for xx in x:
    l.append(np.sin(xx))
y = np.array(l)

# %% [markdown] slideshow={"slide_type": "slide"}
# ## Pyplot

# %% slideshow={"slide_type": "-"}
import matplotlib.pyplot as plt
# %matplotlib inline

# %% slideshow={"slide_type": "fragment"}
x = np.linspace(0, 5*np.pi)
y = np.cos(x)
plt.plot(x, y); # Polygozug zu den Punkten (x[i], y[i]) i = 0 ...

# %%
plt.plot(x, y, 'rx'); 

# %% [markdown] slideshow={"slide_type": "fragment"}
# Farben als Kürzel
#
# |b   |g    |r  |c   |m      |y     |k    |w    |
# |----|-----|---|----|-------|------|-----|-----|
# |blue|green|red|cyan|magenta|yellow|black|white|

# %%
linestyles = ['-', '--', '-.', ':']

# %%
for count, ls in enumerate(linestyles):
    plt.plot([count, count], [0, 1], ls, linewidth=3)

# %%
markers = ['.', ',', 'o', '^', 'v', '<', '>', '1', '2', '3', '4', 's', 'p',]
markers += ['*', 'h', 'H', '+', 'x', 'D', 'd', '|', '_']
y = np.linspace(0, 1, 4)
x = np.zeros_like(y)
for i, m in enumerate(markers):
    plt.plot(x+i, y, m, markersize=11)


# %% slideshow={"slide_type": "slide"}
x = np.linspace(0, 5*np.pi, 201)
y = np.cos(x)
plt.plot(x, y, 'c', linewidth=2); # das ; unterdrückt die Ausgabe

# %% [markdown] slideshow={"slide_type": "slide"}
# Mehrere Graphen in einem Bild

# %%
z = np.sin(x**2)
plt.plot(x, y)
plt.plot(x, z); 

# %% [markdown]
# Hier gibt es immer noch nicht genug Punkte

# %% slideshow={"slide_type": "slide"}
x = np.linspace(0, 5*np.pi, 1101)
y = np.cos(x)
z = np.sin(x**2)
plt.plot(x, y)
plt.plot(x, z);

# %% [markdown] slideshow={"slide_type": "slide"}
# ### Abschnittsweise definierte Funktionen / Slicing

# %%
x = np.linspace(-1, 3, 200)
y = 1/(x**3-1)
plt.plot(x, y);

# %% [markdown] slideshow={"slide_type": "slide"}
# Der Sprung von $-\infty$ nach $\infty$ muss weg:

# %%
b = y>0
c = y<0
plt.plot(x[b], y[b], 'c')
plt.plot(x[c], y[c], 'b');

# %% [markdown] slideshow={"slide_type": "slide"}
# Ausschnitt festelgegen

# %%
b = y>0
c = y<0
plt.plot(x[b], y[b], color='purple')
plt.plot(x[c], y[c], 'b')
plt.axis(ymin=-3, ymax=3);

# %%
b = y>0
c = y<0
plt.plot(x[b], y[b], color='purple')
plt.plot(x[c], y[c], 'b')
plt.ylim([-3,3])
plt.xlim([-3,3])

# %% [markdown]
# https://matplotlib.org/stable/gallery/color/named_colors.html

# %% [markdown] slideshow={"slide_type": "slide"}
# Format ändern, Titel und Legende

# %%
x = np.linspace(-5, 5, 200)
plt.figure(None, (12, 2))
plt.plot(x, np.sinc(x), label='$\sin(x)/x$')
plt.title("Graph der Sincfunktion")
plt.legend(loc="upper right");

# %% [markdown] slideshow={"slide_type": "slide"}
# Dasselbe objektorientiert

# %%
fig = plt.figure(None, (12, 2)) # figure Objekt
ax = fig.gca()   # "get current axes" Koordinatensystem 
ax.plot(x, np.sin(3*np.pi*x), 'w')
ax.set_title("Sinus")
ax.set_facecolor('k')

# %%
fig, axs = plt.subplots(2,1)   # 2 x 1 Koordinatensysteme 
axs[0].plot(x, np.sin(3*np.pi*x), 'w')
axs[1].plot(x, np.cos(2*np.pi*x), 'w')
axs[0].set_title('Sinus')
axs[1].set_title('Cosinus')
for ax in axs:
    ax.set_facecolor('k')

# %%
from itertools import product, combinations
for p1, p2 in combinations(np.array(list(product([-1, 1], repeat=2))), 2):  
    if np.sum((p1-p2)**2) == 4: # Diagonale(n) entfernen
        plt.plot(*zip(p1,p2))


# %%
list(product([-1, 1], repeat=2)) # (karthesiches Produkt [-1,1] x [-1,1])


# %%
def n_eck(n):
    ''' Eckpunkte eines n-Ecks'''
    x = [np.sin(2*np.pi*j/n) for j in range(n+1)]
    y = [np.cos(2*np.pi*j/n) for j in range(n+1)]
    return x, y


# %%
for n in range(3, 9):
    plt.plot(*n_eck(n))  # <- Auspacken
plt.axis('image');
