1

I'm trying to Add the slider in the plot similar to the slider demo example.

I'm plotting fill_between which gives PolyCollection object.

Although I tried with plot too which give Line2D object as shown picture below, but plot doesn't update as expected as in demo.

enter image description here

code

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

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()
plt.subplots_adjust(bottom=0.25)
ax.fill_between(*get_pdf(0, 1), alpha=0.7)
# t = plt.fill_between(*get_pdf(2, 1), alpha=0.7) # this gives ployCollection
t = ax.plot(*get_pdf(2, 1), label='treatment', alpha=0.7)

a = plt.axes([0.25, 0.1, 0.5, 0.03])

slider = widgets.Slider(a, "shift", 0, 10, valinit=2, valstep=1)
def update(val):
    x, y = get_pdf(val)
    t[0].set_ydata(y)
    fig.canvas.draw_idle()

slider.on_changed(update)
plt.show()

rho
  • 771
  • 9
  • 24

1 Answers1

2

To update the line plot, t[0].set_xdata(x) needs to be set, as it is different for each call. In this particular case, get_pdf each time returns the same y.

Updating the coordinates of the polyCollection generated by fill_between doesn't seem to be possible. However, you can delete and recreate it at every update. Note that this is slower than just updating the coordinates.

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

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()
plt.subplots_adjust(bottom=0.25)
ax.fill_between(*get_pdf(0, 1), alpha=0.7)
t = ax.fill_between(*get_pdf(2), color='crimson', alpha=0.7)
a = plt.axes([0.25, 0.1, 0.5, 0.03])

slider = widgets.Slider(a, "shift", 0, 10, valinit=2, valstep=1)
def update(val):
    global t
    t.remove()
    t = ax.fill_between(*get_pdf(val), color='crimson', alpha=0.7)
    fig.canvas.draw_idle()

slider.on_changed(update)
plt.show()
JohanC
  • 71,591
  • 8
  • 33
  • 66
  • after your sugession, i made few improvement and posted in https://codereview.stackexchange.com/questions/243048/matplotlib-fixing-axis-scale-and-alignment – rho May 28 '20 at 04:38
  • any idea what to do with the histogram plot? i did `del t` it doesn't clear the old plot. – rho May 28 '20 at 09:38