import matplotlib.pyplot as plt

"""
Explanation: <a href="https://colab.research.google.com/github/maxkleiner/maXbox4/blob/master/BASTA_2020_matplotlib_presentation2.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>
Session BASTA 2020 & EKON 24: Matplotlib
For matplotlib, we will directly learn through examples. This is much easier as you can directly look at the results on the plots

matplotlib ist das Python Modul zur grafischen Darstellung von Daten.
Es ist ähnlich zu den Grafischen Funktionen von Matlab
matplotlib.pyplot enthält die Funktionen um Graphen zu erstellen.
Es wird oft als plt importiert:
End of explanation
"""


%matplotlib inline

"""
Explanation: Diese nächste Linie ist nur um plots in jupyter notebooks zu darstellen
End of explanation
"""


import numpy as np
x = np.arange(-5,5.01,0.5)
y1 = 1*x + 1.5 +np.random.normal(0, 1, len(x))
y2 = 2*x +np.random.normal(0, 1, len(x))

"""
Explanation: Zuerst generieren wir daten für die plots
End of explanation
"""


plt.figure()
plt.plot(x, y1)
plt.show()
#plt.savefig("path/to/plot.png")
plt.close()

"""
Explanation: Daten plotten

Die plt.figure Funktion generiert eine neue Figur
Mit der plt.plot Funktion kann man Daten plotten.
plt.show zeigt den plot auf dem Bildschirm
plt.savefig speichert die Figur
plt.close schliesst die Figur
End of explanation
"""


plt.figure()
plt.plot(x, y1, "b")
plt.plot(x, y2, "g--")
plt.show()
plt.close()

"""
Explanation: Linie und Symbol formattierung

plt.plot nimmt als Optionales Positional Argument eine format string, um Farbe, Linie/Symbol zu kontrollieren
End of explanation
"""


plt.figure()
plt.plot(x, y1, marker="x", color="g")
plt.plot(x, y2, linestyle="--", color="m")
plt.show()
plt.close()

"""
Explanation: Anstatt der Format string kann man auch alles einzel kontrollieren:
* color: Farbe
* linestyle: Linien Typ
* marker: Symbol
End of explanation
"""


plt.figure()
plt.plot(x, y1, marker="x", color="g", markersize=10)
plt.plot(x, y2, linestyle="--", color="m", linewidth=4)
plt.show()
plt.close()

"""
Explanation: Man kann noch viel mehr mit den keyword argumenten kontrollieren. Zum Beispiel:
* markersize: grösse der Symbole
* linewidth: breite der Striche
End of explanation
"""


plt.figure()
plt.plot(x, y1, "ro", label="y1")
plt.plot(x, y2, "g--", label="y2")
plt.legend(loc="best")
plt.show()
plt.close()

"""
Explanation: Daten Labels

labelkeyword in plt.plot, um einer Linie einen Namen zu geben
Labels werden mit plt.legend() angezeigt
End of explanation
"""


plt.figure()
plt.plot(x, y1)
plt.xlabel("x-label")
plt.ylabel("y-label")
plt.title("My plot title")
plt.show()
plt.close()

"""
Explanation: Title und Achsen Labels
plt hat Funktionen um alle Aspekten von der Figur zu Kontrollieren:
* plt.title um einen Title zu setzen
* plt.xlabel und plt.ylabel für die Achsen Titeln  zu setzen
* plt.xlim und plt.ylim um die Achsen Limiten zu setzen
End of explanation
"""


plt.figure()
plt.plot(x, y1)
plt.xlabel("x-label", fontsize =24)
plt.ylabel("y-label", fontsize =18)
plt.title("My BASTA plot title", fontsize =40)
plt.show()
plt.close()

"""
Explanation: Grösse von den Text Elementen werden mit fontsize kontrolliert:
End of explanation
"""


plt.figure()
plt.plot(x, y1)
plt.xlabel("distance in [$\AA$]")
plt.ylabel("$a*x+b$")
plt.title("My function $\sqrt{f_a(x)}$")
plt.show()
plt.close()

"""
Explanation: In allen Text Felder kann man auch die Latex syntax brauchen um Mathematische symbolen zu representieren. Einfach das Latex zwischen $ zeichen:
End of explanation
"""


plt.figure(figsize = (8, 4))
plt.plot(x, y1, color = 'r', label="line")
plt.plot(x, y2, 'x', markersize = 10,label="markers")
plt.legend(loc="best")
plt.show()
plt.close()

"""
Explanation: Figur grösse
Die grösse der Figur wird in plt.figure() mit figsize angegeben:
End of explanation
"""


plt.figure()
plt.plot(x, y1)
plt.xlim((1, 5))
plt.ylim((-10, 10))
plt.xscale("log")
plt.plot(x, y2)
plt.xscale("linear")
plt.show()
plt.close()

"""
Explanation: Achsen kontrollieren

plt.xlim und plt.ylim um der range von den Achsen zu kontrollieren
plt.xscale("log") für ein logaritmischer Achsen
End of explanation
"""


y1_err = np.random.normal(0, 1, len(x))
x_err = np.random.normal(0, 1, len(x))
plt.figure()
plt.errorbar(x, y1, yerr=y1_err, marker = "o", capsize = 5)
plt.errorbar(x, y2, xerr=x_err, marker = "x", capsize = 6)
plt.show()
plt.close()

"""
Explanation: Errorbar plotten
Errorbars werden mit plt.errorbar erstellt
End of explanation
"""


norm_dist = np.random.normal(0, 1, 500)
plt.hist(norm_dist)
plt.show()
plt.close()

"""
Explanation: Histograms
plt.hist(data) rechnet das hitogram von den daten in data, und generiert direkt einen plot
End of explanation
"""


plt.hist(norm_dist, density=True, bins=20)
plt.show()
plt.close()

"""
Explanation: nbins kontrolliert wieviele bins man brauchen will.
normed kontrolliert ob man die Number von Daten in jedem bin will oder die Probabilität Verteilung
End of explanation
"""


norm_dist1 = np.random.normal(0, 1, 1000)
norm_dist2 = np.random.normal(1, 0.5, 1000)
plt.hist([norm_dist1,norm_dist2], bins=20, density=True)
plt.show()
plt.close()

"""
Explanation: Mann kann auch das histogram für mehrere datensätze gleichzeitig rechnen
End of explanation
"""


hist_y, hist_x, p = plt.hist(norm_dist1, bins=20, density=True)
hist_x = 0.5 * (hist_x[1:] + hist_x[:-1])
plt.close()
plt.figure()
plt.plot(hist_x, hist_y, "rx-")
plt.show()
plt.close()

"""
Explanation: Die plt.hist funktion gibt die bin Anfang und Ende, die Werte, und dir Patches zurück. Mann kann das brauchen um einen Normaler Linien Plot zu generieren, der einfacher Lesbar ist
End of explanation
"""


plt.hist([norm_dist1,norm_dist2], bins=20, density=True)
plt.hlines(0.5, plt.xlim()[0], plt.xlim()[1], linestyle=":", color="r")
plt.vlines([0,1.0],*plt.ylim(),linestyle = "--")
plt.show()
plt.close()

"""
Explanation: Linien und text

plt.vlines um vertikale Linien hinzufügen
plt.hlines um horizontale Linien hinzufügen

Die nehmen als erstes argument die Position (oder eine Liste von Positionen) wo die Liene sein soll, und dann wo si anfängt und aufhört
End of explanation
"""


plt.figure()
plt.plot(x, y1,"x")
plt.text(0,0, "text at position 0,0", fontsize=16)
plt.annotate("point to 1,1",xy=(1, 1), xytext=(3, 2),arrowprops=dict(facecolor='black'))
plt.show()
plt.close()

"""
Explanation: plt.text(xpos, ypos, text) um text hinzufügen an der Position (xpos, ypos)
plt.annotate(text, xy=(xpos, ypos), xytext=(text_x, text_y)) um text hinzufügen an der Position (text_x, text_y) mit einem Pfeil der auf (xpos, ypos) zeigt.
End of explanation
"""


f, axes = plt.subplots(2,2,sharey = "row", figsize = (10,8))
f.suptitle("overall title")
axes[0,0].plot(x,y1)
axes[0,1].errorbar(x, y2, y1_err, capsize = 5)
axes[1,0].hist(norm_dist1, density=True, bins=20)
axes[1,1].hist(norm_dist1, density=True, bins=20, cumulative=True)
for i,axl in enumerate(axes):
    for j,ax in enumerate(axl):
        ax.set_title("subtitle ({},{})".format(i,j))
        ax.set_xlabel("x-label ({},{})".format(i,j))
    axl[0].set_ylabel("y-label")
plt.subplots_adjust(right = 0.98, wspace = 0.02, hspace = 0.25)
plt.show()

"""
Explanation: Subplots

Eine Figure mit mehreren Plots wird mit plt.subplots generiert. Gibt die Figur und eine liste von axes zurück
Dan einfach die elementen von axes brauchen um zu plotten
mit plt.subplots_adjust kann man die position von den subplots kontrollieren

Für axes Objekten werden mehrere Methoden von plt umgenennt: set_ wird vor dem Namen eingefügt. Zum Beispiel:
* plt.title -> ax.set_title
* plt.xlabel -> ax.set_xlabel
* plt.xlim -> ax.set_xlim
End of explanation
"""


import matplotlib as mpl
mpl.rcParams['font.size'] = 18
mpl.rcParams['legend.fontsize'] = 16
mpl.rcParams['xtick.labelsize'] = 20
mpl.rcParams['xtick.top'] = True
mpl.rcParams['xtick.major.size'] = 12
plt.hist([norm_dist1,norm_dist2], bins=20, density=True)
plt.show()
plt.close()

"""
Explanation: Alle defaults kontrollieren
Alle defaults befinden sich in matplotlib.rcParams. Die kann mann verändern und es kontrolliert alle plots. rcParams ist ein dictionnary.
End of explanation
"""


