#!/usr/bin/env python
# coding: utf-8

# <h1>Table of Contents<span class="tocSkip"></span></h1>
# <div class="toc"><ul class="toc-item"><li><span><a href="#Matplotlib-(Teil-2)" data-toc-modified-id="Matplotlib-(Teil-2)-1"><span class="toc-item-num">1&nbsp;&nbsp;</span>Matplotlib (Teil 2)</a></span><ul class="toc-item"><li><span><a href="#Wiederholung" data-toc-modified-id="Wiederholung-1.1"><span class="toc-item-num">1.1&nbsp;&nbsp;</span>Wiederholung</a></span></li><li><span><a href="#Achsen-und-Gitterlinien" data-toc-modified-id="Achsen-und-Gitterlinien-1.2"><span class="toc-item-num">1.2&nbsp;&nbsp;</span>Achsen und Gitterlinien</a></span></li><li><span><a href="#Reihenfolge-der-Elemente-festlegen" data-toc-modified-id="Reihenfolge-der-Elemente-festlegen-1.3"><span class="toc-item-num">1.3&nbsp;&nbsp;</span>Reihenfolge der Elemente festlegen</a></span></li><li><span><a href="#Bilder-abspeichern" data-toc-modified-id="Bilder-abspeichern-1.4"><span class="toc-item-num">1.4&nbsp;&nbsp;</span>Bilder abspeichern</a></span></li><li><span><a href="#Logarithmische-Skalierung" data-toc-modified-id="Logarithmische-Skalierung-1.5"><span class="toc-item-num">1.5&nbsp;&nbsp;</span>Logarithmische Skalierung</a></span></li><li><span><a href="#Vektorpfeile" data-toc-modified-id="Vektorpfeile-1.6"><span class="toc-item-num">1.6&nbsp;&nbsp;</span>Vektorpfeile</a></span></li><li><span><a href="#Flächen-füllen" data-toc-modified-id="Flächen-füllen-1.7"><span class="toc-item-num">1.7&nbsp;&nbsp;</span>Flächen füllen</a></span></li><li><span><a href="#Zeichnen-von-2d-reellwertigen-Daten" data-toc-modified-id="Zeichnen-von-2d-reellwertigen-Daten-1.8"><span class="toc-item-num">1.8&nbsp;&nbsp;</span>Zeichnen von 2d reellwertigen Daten</a></span></li></ul></li><li><span><a href="#3D-Plots" data-toc-modified-id="3D-Plots-2"><span class="toc-item-num">2&nbsp;&nbsp;</span>3D Plots</a></span><ul class="toc-item"><li><span><a href="#Polygonzug-in-3d-mit--plot3D" data-toc-modified-id="Polygonzug-in-3d-mit--plot3D-2.1"><span class="toc-item-num">2.1&nbsp;&nbsp;</span>Polygonzug in 3d mit  <strong>plot3D</strong></a></span></li><li><span><a href="#Fläche-in-3d-mit-surface" data-toc-modified-id="Fläche-in-3d-mit-surface-2.2"><span class="toc-item-num">2.2&nbsp;&nbsp;</span>Fläche in 3d mit <strong>surface</strong></a></span></li><li><span><a href="#Vektorpfeile-in-3d-mit-quiver" data-toc-modified-id="Vektorpfeile-in-3d-mit-quiver-2.3"><span class="toc-item-num">2.3&nbsp;&nbsp;</span>Vektorpfeile in 3d mit <strong>quiver</strong></a></span></li></ul></li></ul></div>

# # Matplotlib (Teil 2)

# In[1]:


import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['figure.figsize'] = (9., 3.)
plt.rcParams['lines.linewidth'] = 3
#%matplotlib qt
get_ipython().run_line_magic('matplotlib', 'notebook')


# In[2]:


#plt.rcParams.keys()


# https://matplotlib.org/stable/gallery/color/named_colors.html

# ## Wiederholung

# In[3]:


fig, ax = plt.subplots(1, 3, layout='constrained')
fig.suptitle('super titel')
fig.set_facecolor('azure')

ax[0].set_title('ax 1 title right', loc='right', color='purple', fontsize=8)
ax[0].set_facecolor('navy')


# In[4]:


def f(t):
    return t**2 * np.exp(-t**2)


t = np.linspace(0, 3, 51)
y = f(t)

ax[0].plot(t, y, color='yellow', label='$t^2\\exp(-t^2)$')
ax[0].legend();


# ## Achsen und Gitterlinien 
# Hinzufügen von Achsenbezeichnungen. Das _layout='constrained'_ in der subplots methode sorgt dafür das alles sichtbar bleibt.

# In[7]:


ax[0].set_xlabel('t', color='red', fontsize=24)
ax[0].set_ylabel('f(t)');


# In[8]:


ax[1].set_facecolor('grey')
ax[1].grid(color='white')
ax[1].plot(y, t, color='gold', alpha=.5);


# In[9]:


phi = np.linspace(0, 2 * np.pi)
ax[2].clear()
ax[2].plot(np.cos(phi), np.sin(phi), 'm', zorder=1)

ax[2].scatter(np.cos(phi[::5]), np.sin(phi[::5]), s=20 + 10 * phi[::5])

ax[2].set_aspect('equal')

# Setze die bottom und left Achsen (engl. spines) als x und y Achse
ax[2].spines['bottom'].set_position('zero')
ax[2].spines['left'].set_position('zero')
# Entferne top und right spines
ax[2].spines['top'].set_visible(False)
ax[2].spines['right'].set_visible(False)


# In[11]:


ax[2].set_xlim((-2, 2))
ax[2].set_ylim((-2, 2))
ax[2].set_xticks([-1, 0, 1])
ax[2].set_yticks([-1, 0, 1]);


# ## Reihenfolge der Elemente festlegen 
# _zorder_ legt fest in welcher Reihenfolge die Elemente gezeichnet werden.

# In[12]:


x = np.linspace(0, 7)

plt.figure()
plt.plot(x, np.sin(x), label='zorder=2', color='blue', zorder=2)
plt.plot(x, np.sin(x + 1), label='zorder=3', color='orange', zorder=3)
plt.axhline(0, label='zorder=2.5', color='lightgrey', zorder=2.5)

plt.title('z order der Element')
l = plt.legend(loc='upper right')
l.set_zorder(2.5)
plt.show()


# Position der Legende 
# 
# | Location String |  Location Code |
# | :- | :-: |
# |'best'|  0 |
# 'upper right' |    1
# 'upper left'  |   2
# 'lower left'  |  3
# 'lower right' |  4
# 'right'       |  5
# 'center left' |  6
# 'center right'|  7
# 'lower center'|  8
# 'upper center'|  9
# 'center'      |  10

# ## Bilder abspeichern
# Bild in einer Datei (pdf, jpeg, ...) speichern:
# 
# __savefig__

# In[13]:


fig.savefig('bild1.pdf')  # das format wird anhand der Endung geraten


# In[14]:


fig.savefig('bild1.jpg', format='jpg')


# In[16]:


#fig.canvas.get_supported_filetypes_grouped()


# ## Logarithmische Skalierung
# Verwendung logarithmischer Achsen:

# In[18]:


x = np.linspace(1, 10, 21)
y = 2**(-x)
fig, ax = plt.subplots(1)
ax.semilogy(x, y, '+');


# Siehe auch semilogx() und loglog(), wenn die x-Achse bzw. beide Achsen logarithmisch skaliert werden sollen

# ## Vektorpfeile
# Vektorpfeile mit
# 
# __quiver__

# In[19]:


fig, ax = plt.subplots(figsize=(3, 3))
x, y, u, v = 0, 0, 1, .5

ax.quiver(x, y, u, v)  # (x,y) Fusspunkt (u,v) Richtung
ax.set_title('Quiver mit einem Pfeil')
ax.axis([-2, 2, -2, 2])
ax.grid()


# In[20]:


fig, ax = plt.subplots(figsize=(3, 3))
x, y, u, v = 0, 0, 1, .5

ax.quiver(x, y, u, v, angles='xy', scale_units='xy', scale=1)
ax.set_title('Quiver mit einem Pfeil')
ax.axis([-2, 2, -2, 2])
ax.grid()
ax.set_aspect('equal')


# In[21]:


fig, ax = plt.subplots(figsize=(3, 3))
n = 7
t = np.linspace(0, 2 * np.pi, n)[:-1]
x = np.cos(t)
y = np.sin(t)
u = np.sin(t)
v = -np.cos(t)
color = t
ax.scatter(x, y, s=5 * t + 5, c=color, cmap='plasma')

qv = ax.quiver(x, y, u, v,  color, angles='xy', scale_units='xy',
               scale=1, cmap='plasma')
ax.set_title('Quiver mit vielen Pfeilen')
ax.axis([-2, 2, -2, 2])
ax.set_aspect('equal')

fig.colorbar(qv);


# Der Parameter __cmap__ wählt die Colormap aus.  
# Link zu Colormaps (cmap) https://matplotlib.org/stable/tutorials/colors/colormaps.html

# ## Flächen füllen
# 
# __fill__

# In[23]:


fig, ax = plt.subplots(1)
ax.plot([0, 1, 0, 0], [0, 0, 1, 0])
ax.axis(xmin=-.01, ymin=-.01);


# In[24]:


fig, ax = plt.subplots(1)
ax.fill([0, 1, 0, 0], [0, 0, 1, 0], color='red')
ax.axis(xmin=-.01, ymin=-.01);


# In[25]:


x = np.linspace(0, 1.8 * np.pi)
y1 = np.sin(x)


# In[27]:


fig, ax = plt.subplots(1)
ax.fill(x, y1)
ax.plot(x, y1, 'xr')
ax.axis('equal');


# ## Zeichnen von 2d reellwertigen Daten
# 
# __imshow__

# In[29]:


M = (-1)**np.arange(25).reshape(5, 5)
fig, ax = plt.subplots(1)
ax.imshow(M, cmap='Greys');


# In[ ]:


plt.close('all')


# In[30]:


from matplotlib.image import imread

img = imread('bild1.jpg')
img.shape


# In[31]:


plt.figure()
plt.imshow(img)


# In[33]:


fig, ax = plt.subplots(1)
x = np.linspace(-2, 2)
y = np.linspace(-2, 2)
xx, yy = np.meshgrid(x, y)
zz = xx**2 - yy**2
cs = ax.contour(xx, yy, zz, [-1, 1])
cs.clabel()
ax.axis('equal');


# # 3D Plots

# ## Polygonzug in 3d mit  __plot3D__

# In[35]:


x = np.random.rand(5)
y = np.random.rand(5)
z = np.random.randn(5)

ax = plt.figure().add_subplot(projection='3d')
ax.plot(x, y, z, 'co-');


# ## Fläche in 3d mit __surface__

# In[38]:


fig, ax = plt.subplots(1, 2, layout='constrained', subplot_kw={'projection': '3d'})

phi = np.linspace(0, 2 * np.pi, 12)
phi = np.append(phi, np.nan).reshape(
    -1, 1)  # NaN Trick damit keine ungewollten Linien entstehen
theta = np.linspace(0, np.pi, 12)
theta = np.append(theta, np.nan).reshape(1, -1)

# Parametrisierung der Kugelfläche siehe https://de.wikipedia.org/wiki/Kugel
x = np.cos(phi) * np.sin(theta)  # durch broadcasting sind x, y, z hier 2D arrays
y = np.sin(phi) * np.sin(theta)
z = np.ones_like(phi) * np.cos(theta)

ax[0].plot(x.flatten(), y.flatten(), z.flatten(), 'r*-', linewidth=1)
ax[1].plot_surface(x, y, z);


# In[39]:


from itertools import product, combinations

fig = plt.figure(figsize=(4, 4))
ax = fig.add_subplot(projection='3d')

#Wuerfel
r = [-1, 1]
for p1, p2 in combinations(np.array(list(product(r, repeat=3))), 2):
    if np.sum(np.abs(p1 - p2)) == r[1] - r[0]:  # falls die Kantenlänge 2 ist
        ax.plot3D(*zip(p1, p2), color="b", alpha=0.5)

ax.set_box_aspect((1, 1, 1))


# ## Vektorpfeile in 3d mit __quiver__

# In[41]:


fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(projection='3d')

phi = np.linspace(0, 2 * np.pi, 6)
phi = np.append(phi, np.nan).reshape(
    -1, 1)  # NaN Trick damit keine ungewollten Linien entstehen
theta = np.linspace(0, np.pi, 6)
theta = np.append(theta, np.nan).reshape(1, -1)

u = np.cos(phi) * np.sin(
    theta)  # durch broadcasting sind x, y, z hier 2D arrays
v = np.sin(phi) * np.sin(theta)
w = np.ones_like(phi) * np.cos(theta)

ax.quiver(0, 0, 0, u, v, w);


# In[42]:


ax.set_xlim(-2, 2)
ax.set_ylim(-2, 2)
ax.set_zlim(-2, 2)


# In[ ]:


plt.close('all')


# In[ ]:




