import pylab as plt
import numpy as np
import numpy.linalg as alg
import matplotlib as mpl
from matplotlib.widgets import Slider, Button

mpl.rcParams['text.usetex'] = False #True pour mettre du beau LateX mais ça fait laguer ou False c'est moche mais ça lag pas
mpl.rcParams['axes.titlesize'] = 15
mpl.rcParams['axes.labelsize'] = 30
mpl.rcParams['lines.linewidth'] = 3
mpl.rcParams['lines.markersize'] = 8
mpl.rcParams['xtick.labelsize'] = 20
mpl.rcParams['ytick.labelsize'] = 20
mpl.rcParams['legend.fontsize'] = 25

#Calul des statistiques en thermodynamique statistique 

##Le gros du calcul

# The parametrized function to be plotted
def to_plot(E,mu,T) : 
    T = 10**(T) #Le slider fait varier les valeurs de T en log on le convertit ici
    BE = 1/(np.exp((E-mu)/T)-1)#Statistique de Bose-Einstein
    FD = 1/(np.exp((E-mu)/T)+1)#Fermi-Dirac
    MB = np.exp(-E/T)#Maxwell-Boltzmann
    P = 1/(np.exp(E/T)-1)#Planck (BE avec mu=0, pour les photons et les phonons)
    
    return BE,FD,MB,P
    
    
E = np.linspace(0,500,50000)

##Le plot avec sliders
# Define initial parameters
init_mu = 5
init_T = 0.1


# Create the figure and the line that we will manipulate
fig, ax = plt.subplots()
BE,FD,MB,P=to_plot(E, init_mu, init_T)
ind=np.where(BE>0)
BE0 = BE[ind]
E0 = E[ind]
lineBE, = plt.plot(E0, BE0,label='Bose-Einstein')
lineFD, = plt.plot(E, FD,label='Fermi-Dirac')
lineMB, = plt.plot(E, MB,label='Maxwell-Boltzmann')
lineP, = plt.plot(E, P,label='Planck')
linemu = plt.axvline(init_mu,linestyle='--',color='black')
ax.set_xlabel(r'$E$')
ax.set_ylabel('Probabilité')
ax.set_xlim(0,np.max([E[np.where(BE<0.01)[0][0]],E[np.where(FD<0.01)[0][0]],E[np.where(MB<0.01)[0][0]],E[np.where(P<0.01)[0][0]]]))
ax.set_ylim(0,2)

# Adjust the main plot to make room for the sliders
#plt.subplots_adjust(left=0.25, bottom=0.25)
plt.subplots_adjust(left=0.1,bottom=0.25,top=0.95)

# Make horizontal sliders to control the parameters.
ax_mu = plt.axes([0.1, 0.07, 0.8, 0.03])
mu_slider = Slider(
    ax=ax_mu,
    label=r'$\mu$',
    valmin=0.01,
    valmax=100,
    valinit=init_mu,
)
mu_slider.label.set_size(20)
mu_slider.valtext.set_fontsize(20)

ax_T = plt.axes([0.1, 0.1, 0.8, 0.03])
T_slider = Slider(
    ax=ax_T,
    label=r'$k_B\,T$',
    valmin=-2,
    valmax=2,
    valinit=init_T,
)
T_slider.label.set_size(20)
T_slider.valtext.set_fontsize(20)
T_slider.valtext.set_text(10**T_slider.val)#pour afficher la 'vraie' valeur de la température



# The function to be called anytime a slider's value changes
def update(val):
    BE,FD,MB,P=to_plot(E, mu_slider.val, T_slider.val)
    ind=np.where(BE>0)
    BE0 = BE[ind]
    E0 = E[ind]
    lineBE.set_xdata(E0)
    lineBE.set_ydata(BE0)
    lineFD.set_ydata(FD)
    lineMB.set_ydata(MB)
    lineP.set_ydata(P)
    linemu.set_xdata(mu_slider.val)
    T_slider.valtext.set_text(round(10**T_slider.val,2))
    ax.set_xlim(0,np.max([E[np.where(BE<0.01)[0][0]],E[np.where(FD<0.01)[0][0]],E[np.where(MB<0.01)[0][0]],E[np.where(P<0.01)[0][0]]]))
    fig.canvas.draw_idle()


# register the update function with each slider
mu_slider.on_changed(update)
T_slider.on_changed(update)

# Create a `matplotlib.widgets.Button` to reset the sliders to initial values.
resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
button = Button(resetax, 'Reset', hovercolor='0.975')

def reset(event):
    mu_slider.reset()
    T_slider.reset()
    
button.on_clicked(reset)

ax.legend(loc='upper right')
plt.show()


