import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.patches import ConnectionPatch, Rectangle
from scipy.stats import uniform as un
from functools import partial
def pdf(x):
    if (x < 1):
        return 0
    elif (x >= 1) and (x <= 5):
        return (5 / 4) * (1 / (x ** 2))
    else:
        return 0

def cdf(x):
    if (x < 1):
        return 0
    elif (x >= 1) and (x <= 5):
        return (5*x - 5) / (4 * x)
    else:
        return 1


fig, (ax_pdf, ax_cdf) = plt.subplots(
    nrows=2,
    sharex=True,
    figsize=(6, 6),
)

plt.rcParams['axes.grid'] = True
plt.rc('legend', fontsize=15)
fig.suptitle('In class example', fontsize=16)
x = np.arange(-1, 8, 0.01)
Nx = x.shape[0]
y_pdf = np.empty((Nx))
y_cdf = np.empty((Nx))
for i in range(Nx):
    y_pdf[i] = pdf(x[i])
for i in range(Nx):
    y_cdf[i] = cdf(x[i])
ax_cdf.plot(x, y_cdf, label=r'$F_X(x)$')
ax_pdf.plot(x, y_pdf, label=r'$f_X(x)$')

ax_pdf.legend()
ax_cdf.legend()

# plt.show()
# plt.savefig("pdf_cdf_example.pdf")

Y1 = y_pdf
Y2 = np.zeros(x.shape[0])

x_a, y_a = x[300], cdf(x[300])
x_b, y_b = x[500], cdf(x[500])


# draw full curve to set view limits in right Axes
# Plot the 0th frame
fill_a = ax_pdf.fill_between(x[:300], Y1[:300], color='m', alpha=0.6, label=r'$P(X < 2)$ = F_X(2)')
fill = ax_pdf.fill_between(x[:500], Y1[:500], color='g', alpha=0.4, label=r'$P(X < 4)$ = F_X(4)')
point, = ax_cdf.plot(x[0], 0, "o", color='m')
point.set_data([x_a], [y_a])
point_b, = ax_cdf.plot(x[0], 0, "o", color='g')
point_b.set_data([x_b], [y_b])

# draw connecting line between both graphs
con = ConnectionPatch(
    (x[0], 0),
    (x[0], 0),
    "data",
    "data",
    axesA=ax_cdf,
    axesB=ax_pdf,
    color="m",
    ls="dotted",
)
con.xy1 = x_a, y_a
con.xy2 = x_a, 0
fig.add_artist(con)

# draw connecting line between both graphs
con_b = ConnectionPatch(
    (x[0], 0),
    (x[0], 0),
    "data",
    "data",
    axesA=ax_cdf,
    axesB=ax_pdf,
    color="g",
    ls="dotted",
)
con_b.xy1 = x_b, y_b
con_b.xy2 = x_b, 0
fig.add_artist(con_b)

global tmp_vert
tmp_vert = np.zeros((2,2))
tmp_vert[0, 0], tmp_vert[0,0] = x[0], 0
tmp_vert[1, 0], tmp_vert[1,1] = x[0], 0
fill.set_paths([tmp_vert], False)


def animate(i):
    x = np.arange(-1, 8, 0.01)
    add_vert = np.array([x[i], 0])
    path = fill.get_paths()[0]
    vertices = path.vertices
    vertices[-1,0], vertices[-1,1] = x[i], pdf(x[i])
    vertices = np.vstack((vertices, add_vert))
    fill.set_paths([vertices], False)
    

    # # Elements 1:Nx+1 encode the upper curve
    # vertices[1:i + 1, 1] = Y1[:i]
    x, y = x[i], cdf(x[i])
    point.set_data([x], [y])
    con.xy1 = x, y
    con.xy2 = x, 0
    return point, fill, con

fr = np.arange(Nx)
ani = animation.FuncAnimation(
    fig,
    animate,
    interval=7,
    blit=False,  # blitting can't be used with Figure artists
    frames=fr,
    repeat_delay=100,
)

# plt.show()

f = "in_class.gif"
writergif = animation.PillowWriter(fps=15)
ani.save(f, writer=writergif)
x[300]
rv = un(0, 10)

fig, (ax_obj, ax_pdf, ax_cdf) = plt.subplots(
    nrows=3,
    sharex=True,
    figsize=(6, 6),
)
strip = Rectangle((0, 0), 10, 0.2, ec="none")
# ax_pdf.yaxis.set_visible(False)
ax_pdf.set_ylabel(r'$\rho(x)$', rotation='horizontal', labelpad=12)
ax_cdf.set_ylabel(r'$m(x)$', rotation='horizontal', labelpad=12)
fig.suptitle('Physical example', fontsize=16)
x = np.arange(-3, 13.1, 0.1)
Nx = x.shape[0]
ax_obj.get_yaxis().set_visible(False)
ax_obj.add_artist(strip)
y_pdf = rv.pdf(x)
y_cdf = rv.cdf(x)
cdf, = ax_cdf.plot(x, y_cdf, "k")
pdf, = ax_pdf.plot(x, y_pdf)

Y1 = y_pdf
Y2 = np.zeros(x.shape[0])

# draw full curve to set view limits in right Axes
# Plot the 0th frame

fill = ax_pdf.fill_between(x[:2], Y1[:2], color='r', alpha=0.5)
path = fill.get_paths()[0]
vertices = path.vertices
print(vertices)
point, = ax_cdf.plot(x[0], 0, "o", color='r')

# draw connecting line between both graphs
con = ConnectionPatch(
    (x[0], 0),
    (x[0], 0),
    "data",
    "data",
    axesA=ax_cdf,
    axesB=ax_pdf,
    color="r",
    ls="dotted",
)
fig.add_artist(con)
global tmp_vert
tmp_vert = np.zeros((2,2))
tmp_vert[0, 0], tmp_vert[0,0] = x[0], 0
tmp_vert[1, 0], tmp_vert[1,1] = x[0], 0
fill.set_paths([tmp_vert], False)


def animate(i):
    # pdf.set_data(x_dom, norm.pdf(x_dom))
    rv = un(0, 10)
    x = np.arange(-3, 13.1, 0.1)
    add_vert = np.array([x[i], 0])
    path = fill.get_paths()[0]
    vertices = path.vertices
    vertices[-1,0], vertices[-1,1] = x[i], rv.pdf(x[i])
    vertices = np.vstack((vertices, add_vert))
    fill.set_paths([vertices], False)
    

    # # Elements 1:Nx+1 encode the upper curve
    # vertices[1:i + 1, 1] = Y1[:i]
    x, y = x[i], rv.cdf(x[i])
    point.set_data([x], [y])
    con.xy1 = x, y
    con.xy2 = x, 0
    return point, fill, con

fr = np.arange(Nx)
ani = animation.FuncAnimation(
    fig,
    animate,
    interval=7,
    blit=False,  # blitting can't be used with Figure artists
    frames=fr,
    repeat_delay=100,
)

# plt.show()

f = "pic_distrib.gif"
writergif = animation.PillowWriter(fps=10)
ani.save(f, writer=writergif)
l = 5.6+1.53333
def pdf(x):
    l = 5.6+1.53333
    if (x < 0):
        return 0
    elif (x>=0) and (x<4.4):
        return 0.12
    elif (x>=4.4) and (x<=5.6):
        return (-0.5 * (x**2) + 5*x - 12.2)
    elif (x>5.6) and (x<l):
        return 0.12
    else:
        return 0


def cdf(x):
    l = 5.6+1.53333
    if (x < 0):
        return 0
    elif (x>=0) and (x<=4.4):
        return 0.12 * x
    elif (x>4.4) and (x<=5.6):
        return (cdf(4.4) + -0.166667 * (x**3) + 2.5 * (x**2) - 12.2 * x + 19.4773)
    elif (x>5.6) and (x<l):
        return cdf(5.6) + (x-5.6) * 0.12
    else:
        return 1
cdf(5.7)
fig, (ax_obj, ax_pdf, ax_cdf) = plt.subplots(
    nrows=3,
    sharex=True,
    figsize=(6, 6),
)
strip = Rectangle((0, 0), l, 0.2, ec="none")
# ax_pdf.yaxis.set_visible(False)
ax_pdf.set_ylabel(r'$\rho(x)$', rotation='horizontal', labelpad=12)
ax_cdf.set_ylabel(r'$m(x)$', rotation='horizontal', labelpad=12)
fig.suptitle('Physical example 2', fontsize=16)
x = np.arange(-3, 10, 0.1)
Nx = x.shape[0]
y_pdf = np.empty((Nx))
y_cdf = np.empty((Nx))
ax_obj.get_yaxis().set_visible(False)
ax_obj.add_artist(strip)
for i in range(Nx):
    y_pdf[i] = pdf(x[i])
for i in range(Nx):
    y_cdf[i] = cdf(x[i])

cdf_plot, = ax_cdf.plot(x, y_cdf, "k")
pdf_plot, = ax_pdf.plot(x, y_pdf)

Y1 = y_pdf
Y2 = np.zeros(x.shape[0])

# draw full curve to set view limits in right Axes
# Plot the 0th frame
fill = ax_pdf.fill_between(x[:1], Y1[:1], color='r', alpha=0.5)
point, = ax_cdf.plot(x[0], 0, "o", color='r')

# draw connecting line between both graphs
con = ConnectionPatch(
    (x[0], 0),
    (x[0], 0),
    "data",
    "data",
    axesA=ax_cdf,
    axesB=ax_pdf,
    color="r",
    ls="dotted",
)
fig.add_artist(con)

global tmp_vert
tmp_vert = np.zeros((2,2))
tmp_vert[0, 0], tmp_vert[0,0] = x[0], 0
tmp_vert[1, 0], tmp_vert[1,1] = x[0], 0
fill.set_paths([tmp_vert], False)


def animate(i):
    # pdf.set_data(x_dom, norm.pdf(x_dom))
    x = np.arange(-3, 10, 0.1)
    add_vert = np.array([x[i], 0])
    path = fill.get_paths()[0]
    vertices = path.vertices
    vertices[-1,0], vertices[-1,1] = x[i], pdf(x[i])
    vertices = np.vstack((vertices, add_vert))
    fill.set_paths([vertices], False)
    

    # # Elements 1:Nx+1 encode the upper curve
    # vertices[1:i + 1, 1] = Y1[:i]
    x, y = x[i], cdf(x[i])
    point.set_data([x], [y])
    con.xy1 = x, y
    con.xy2 = x, 0
    return point, fill, con

fr = np.arange(Nx)
ani = animation.FuncAnimation(
    fig,
    animate,
    interval=7,
    blit=False,  # blitting can't be used with Figure artists
    frames=fr,
    repeat_delay=100,
)

# plt.show()

f = "strip_with_incl.gif"
writergif = animation.PillowWriter(fps=10)
ani.save(f, writer=writergif)
def pdf(x):
    if (x < 0):
        return 0
    elif (x>=0) and (x<=2):
        return (x**3) / 4
    else:
        return 0


def cdf(x):
    if (x < 0):
        return 0
    elif (x>=0) and (x<=2):
        return (x ** 4) / 16
    else:
        return 1

fig, (ax_pdf, ax_cdf) = plt.subplots(
    nrows=2,
    sharex=True,
    figsize=(6, 6),
)

# ax_pdf.yaxis.set_visible(False)
ax_pdf.set_ylabel(r'$f_X(x)$', rotation='horizontal', labelpad=12)
ax_cdf.set_ylabel(r'$F_X(x)$', rotation='horizontal', labelpad=12)
fig.suptitle(r'$x^3 / 4$ density function', fontsize=16)
x = np.arange(-2, 6, 0.05)
Nx = x.shape[0]
y_pdf = np.empty((Nx))
y_cdf = np.empty((Nx))

for i in range(Nx):
    y_pdf[i] = pdf(x[i])
for i in range(Nx):
    y_cdf[i] = cdf(x[i])

cdf_plot, = ax_cdf.plot(x, y_cdf, "k")
pdf_plot, = ax_pdf.plot(x, y_pdf)

Y1 = y_pdf
Y2 = np.zeros(x.shape[0])

# draw full curve to set view limits in right Axes
# Plot the 0th frame
fill = ax_pdf.fill_between(x[:1], Y1[:1], color='r', alpha=0.5)
point, = ax_cdf.plot(x[0], 0, "o", color='r')

# draw connecting line between both graphs
con = ConnectionPatch(
    (x[0], 0),
    (x[0], 0),
    "data",
    "data",
    axesA=ax_cdf,
    axesB=ax_pdf,
    color="r",
    ls="dotted",
)
fig.add_artist(con)

global tmp_vert
tmp_vert = np.zeros((2,2))
tmp_vert[0, 0], tmp_vert[0,0] = x[0], 0
tmp_vert[1, 0], tmp_vert[1,1] = x[0], 0
fill.set_paths([tmp_vert], False)


def animate(i):
    # pdf.set_data(x_dom, norm.pdf(x_dom))
    x = np.arange(-2, 6, 0.05)
    add_vert = np.array([x[i], 0])
    path = fill.get_paths()[0]
    vertices = path.vertices
    vertices[-1,0], vertices[-1,1] = x[i], pdf(x[i])
    vertices = np.vstack((vertices, add_vert))
    fill.set_paths([vertices], False)
    

    # # Elements 1:Nx+1 encode the upper curve
    # vertices[1:i + 1, 1] = Y1[:i]
    x, y = x[i], cdf(x[i])
    point.set_data([x], [y])
    con.xy1 = x, y
    con.xy2 = x, 0
    return point, fill, con

fr = np.arange(Nx)
ani = animation.FuncAnimation(
    fig,
    animate,
    interval=7,
    blit=False,  # blitting can't be used with Figure artists
    frames=fr,
    repeat_delay=100,
)

# plt.show()

f = "3a.gif"
writergif = animation.PillowWriter(fps=10)
ani.save(f, writer=writergif)
def pdf(x):
    if (x < 0):
        return 0
    elif (x>=0) and (x<=1):
        return 2 * x
    else:
        return 0


def cdf(x):
    if (x < 0):
        return 0
    elif (x>=0) and (x<=1):
        return (x ** 2)
    else:
        return 1

fig, (ax_pdf, ax_cdf) = plt.subplots(
    nrows=2,
    sharex=True,
    figsize=(6, 6),
)

# ax_pdf.yaxis.set_visible(False)
ax_pdf.set_ylabel(r'$f_X(x)$', rotation='horizontal', labelpad=12)
ax_cdf.set_ylabel(r'$F_X(x)$', rotation='horizontal', labelpad=12)
fig.suptitle(r'$2x$ density function', fontsize=16)
x = np.arange(-2, 6, 0.05)
Nx = x.shape[0]
y_pdf = np.empty((Nx))
y_cdf = np.empty((Nx))

for i in range(Nx):
    y_pdf[i] = pdf(x[i])
for i in range(Nx):
    y_cdf[i] = cdf(x[i])

cdf_plot, = ax_cdf.plot(x, y_cdf, "k")
pdf_plot, = ax_pdf.plot(x, y_pdf)

Y1 = y_pdf
Y2 = np.zeros(x.shape[0])

# draw full curve to set view limits in right Axes
# Plot the 0th frame
fill = ax_pdf.fill_between(x[:1], Y1[:1], color='r', alpha=0.5)
point, = ax_cdf.plot(x[0], 0, "o", color='r')

# draw connecting line between both graphs
con = ConnectionPatch(
    (x[0], 0),
    (x[0], 0),
    "data",
    "data",
    axesA=ax_cdf,
    axesB=ax_pdf,
    color="r",
    ls="dotted",
)
fig.add_artist(con)

global tmp_vert
tmp_vert = np.zeros((2,2))
tmp_vert[0, 0], tmp_vert[0,0] = x[0], 0
tmp_vert[1, 0], tmp_vert[1,1] = x[0], 0
fill.set_paths([tmp_vert], False)


def animate(i):
    # pdf.set_data(x_dom, norm.pdf(x_dom))
    x = np.arange(-2, 6, 0.05)
    add_vert = np.array([x[i], 0])
    path = fill.get_paths()[0]
    vertices = path.vertices
    vertices[-1,0], vertices[-1,1] = x[i], pdf(x[i])
    vertices = np.vstack((vertices, add_vert))
    fill.set_paths([vertices], False)
    

    # # Elements 1:Nx+1 encode the upper curve
    # vertices[1:i + 1, 1] = Y1[:i]
    x, y = x[i], cdf(x[i])
    point.set_data([x], [y])
    con.xy1 = x, y
    con.xy2 = x, 0
    return point, fill, con

fr = np.arange(Nx)
ani = animation.FuncAnimation(
    fig,
    animate,
    interval=7,
    blit=False,  # blitting can't be used with Figure artists
    frames=fr,
    repeat_delay=100,
)

# plt.show()

f = "1.gif"
writergif = animation.PillowWriter(fps=10)
ani.save(f, writer=writergif)
def pdf(x):
    if (x < 10):
        return 0
    else:
        return (10 / x ** 2)


def cdf(x):
    if (x < 10):
        return 0
    else:
        return (1 - 10 / x)

fig, (ax_pdf, ax_cdf) = plt.subplots(
    nrows=2,
    sharex=True,
    figsize=(6, 6),
)

# ax_pdf.yaxis.set_visible(False)
ax_pdf.set_ylabel(r'$f_X(x)$', rotation='horizontal', labelpad=12)
ax_cdf.set_ylabel(r'$F_X(x)$', rotation='horizontal', labelpad=12)
fig.suptitle(r'$10 / x^2$ density function', fontsize=16)
x = np.arange(8, 40, 0.25)
Nx = x.shape[0]
y_pdf = np.empty((Nx))
y_cdf = np.empty((Nx))

for i in range(Nx):
    y_pdf[i] = pdf(x[i])
for i in range(Nx):
    y_cdf[i] = cdf(x[i])

cdf_plot, = ax_cdf.plot(x, y_cdf, "k")
pdf_plot, = ax_pdf.plot(x, y_pdf)

Y1 = y_pdf
Y2 = np.zeros(x.shape[0])

# draw full curve to set view limits in right Axes
# Plot the 0th frame
fill = ax_pdf.fill_between(x[:1], Y1[:1], color='r', alpha=0.5)
point, = ax_cdf.plot(x[0], 0, "o", color='r')

# draw connecting line between both graphs
con = ConnectionPatch(
    (x[0], 0),
    (x[0], 0),
    "data",
    "data",
    axesA=ax_cdf,
    axesB=ax_pdf,
    color="r",
    ls="dotted",
)
fig.add_artist(con)

global tmp_vert
tmp_vert = np.zeros((2,2))
tmp_vert[0, 0], tmp_vert[0,0] = x[0], 0
tmp_vert[1, 0], tmp_vert[1,1] = x[0], 0
fill.set_paths([tmp_vert], False)


def animate(i):
    # pdf.set_data(x_dom, norm.pdf(x_dom))
    x = np.arange(8, 40, 0.25)
    add_vert = np.array([x[i], 0])
    path = fill.get_paths()[0]
    vertices = path.vertices
    vertices[-1,0], vertices[-1,1] = x[i], pdf(x[i])
    vertices = np.vstack((vertices, add_vert))
    fill.set_paths([vertices], False)
    

    # # Elements 1:Nx+1 encode the upper curve
    # vertices[1:i + 1, 1] = Y1[:i]
    x, y = x[i], cdf(x[i])
    point.set_data([x], [y])
    con.xy1 = x, y
    con.xy2 = x, 0
    return point, fill, con

fr = np.arange(Nx)
ani = animation.FuncAnimation(
    fig,
    animate,
    interval=7,
    blit=False,  # blitting can't be used with Figure artists
    frames=fr,
    repeat_delay=100,
)

# plt.show()

f = "2.gif"
writergif = animation.PillowWriter(fps=10)
ani.save(f, writer=writergif)