matplotlib fixing axis scale and alignment There is few points In the script I don't like I think it can be improved, but I need a second opinion, here is the interactive plot I'm trying to build.



here is the code with thought in comments.

#!/usr/bin/python3

from functools import lru_cache

import numpy as np
import scipy.stats as ss
import matplotlib.pyplot as plt
import matplotlib.widgets as widgets

@lru_cache # beacuse it redraws each time
def get_pdf(mu, sigma=1, offset=4):
    o = sigma * offset
    x = np.linspace(mu - o, mu + o, 100)
    rv = ss.norm(mu, sigma)
    return x, rv.pdf(x)

fig, ax = plt.subplots()
# added the subplot for bottom margin and the slider, since its also the ax
plt.subplots_adjust(bottom=0.25)

ax.fill_between(*get_pdf(0), label='A', alpha=0.7)
ax.set_xlim(-10, 10)
ax.set_ylim(0, 1)

# my guess is this has to be integrated with the update rather than outside
# and using t variable as global which I don't like, and guess it can be improved
t = ax.fill_between(*get_pdf(2), label='B', color='crimson', alpha=0.7)

slider = widgets.Slider(
    # ax position are absolute, should be easy without subplot may be
    ax      = plt.axes([0.25, 0.1, 0.5, 0.03]), 
    label   = "shift",
    valmin  = -5,
    valmax  = 5,
    valinit = 2,
    valstep = 0.5
)

def update(val):
    x, y = get_pdf(val)
    global t # really hate to do this
    t.remove()
    t = ax.fill_between(*get_pdf(val), color='crimson', alpha=0.7)
    fig.canvas.draw_idle()

slider.on_changed(update)
ax.legend()
plt.show()
If you want to get rid of the global t you could consider creating a class to manage the data and updating. I quickly whipped something together, although I'm not well versed enough in stats to have a good idea about what names would be more appropriate.

from functools import lru_cache

import numpy as np
import scipy.stats as ss
import matplotlib.pyplot as plt
import matplotlib.widgets as widgets

#probability density function generator: chached
@lru_cache # beacuse it redraws each time
def get_pdf(mu, sigma=1, offset=4):
    o = sigma * offset
    x = np.linspace(mu - o, mu + o, 100)
    rv = ss.norm(mu, sigma)
    return x, rv.pdf(x)

# This simple class will hold the reference to `t` so that it doesn't need to 
# be a global
class Data():
    '''
    A simple class that plots data on an axis and contains a method for updating
    the plot.
    '''

    def __init__(self, ax, **properties):
        self.properties = properties
        self.t = ax.fill_between(*get_pdf(2), **properties)

    def update(self, val):
        x, y = get_pdf(val)
        self.t.remove()
        self.t = ax.fill_between(x, y, **self.properties)
        fig.canvas.draw_idle()


# Generate the figure and axis for our widget

fig, ax = plt.subplots()
# added the subplot for bottom margin and the slider, since its also the ax
plt.subplots_adjust(bottom=0.25)

# add a slider widget
slider = widgets.Slider(
    # ax position are absolute, should be easy without subplot may be
    ax      = plt.axes([0.25, 0.1, 0.5, 0.03]), 
    label   = "shift",
    valmin  = -5,
    valmax  = 5,
    valinit = 2,
    valstep = 0.5
)


# add a reference distribution *A*
ax.fill_between(*get_pdf(0), label='A', alpha=0.7)
ax.set_xlim(-10, 10)
ax.set_ylim(0, 1)

# Create a data instance
properties = dict(label='B', color='crimson', alpha=0.7)
data = Data(ax=ax, **properties)

# link data update method to slider.on_changed
slider.on_changed(data.update)
ax.legend()
plt.show()

```