I'm trying to code an interactive matplotlib plot similar to the one given as answer by @Joe Kington on this post.
The difference is that i'm trying to make the facecolor also vary according to the changes caused by the sliders. Thus, i added some lines of code, resulting in the code below.
The facecolor indeed changes, but not as expected. Somehow the plot just accumulates the colors, resulting in a mess.
I looked for some way to erase the facecolor of the plot before updating it in the sliders_on_changed function, but no sucess.
Can anyone help me?
from numpy import pi, sin
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons
import IPython
from matplotlib import colors
shell = IPython.get_ipython()
shell.enable_matplotlib(gui='qt')
def signal(amp, freq):
df = pd.DataFrame(amp * sin(2 * pi * freq * t),columns = ['values'])
df['positive'] = df['values']>0
return amp * sin(2 * pi * freq * t),df
axis_color = 'lightgoldenrodyellow'
fig = plt.figure()
ax = fig.add_subplot(111)
# Adjust the subplots region to leave some space for the sliders and buttons
fig.subplots_adjust(left=0.25, bottom=0.25)
t = np.arange(0.0, 1.0, 0.001)
amp_0 = 5
freq_0 = 5
df = signal(amp_0, freq_0)[1]
# Draw the initial plot
# The 'line' variable is used for modifying the line later
[line] = ax.plot(t, signal(amp_0, freq_0)[0], linewidth=2, color='red')
ax.set_xlim([0, 1])
ax.set_ylim([-10, 10])
cmap = colors.ListedColormap(['green', 'red'])
ax.pcolorfast(ax.get_xlim(), ax.get_ylim(),
(df['positive'] > 0).apply(lambda x: int(x)).values[np.newaxis],
cmap=cmap, alpha=0.3)
# Add two sliders for tweaking the parameters
# Define an axes area and draw a slider in it
amp_slider_ax = fig.add_axes([0.25, 0.15, 0.65, 0.03], facecolor=axis_color)
amp_slider = Slider(amp_slider_ax, 'Amp', 0.1, 10.0, valinit=amp_0)
# Draw another slider
freq_slider_ax = fig.add_axes([0.25, 0.1, 0.65, 0.03], facecolor=axis_color)
freq_slider = Slider(freq_slider_ax, 'Freq', 0.1, 30.0, valinit=freq_0)
# Define an action for modifying the line when any slider's value changes
def sliders_on_changed(val):
selAmp = amp_slider.val
selFreq = freq_slider.val
df = signal(selAmp, selFreq)[1]
line.set_ydata(signal(selAmp, selFreq)[0])
cmap = colors.ListedColormap(['green', 'red'])
ax.pcolorfast(ax.get_xlim(), ax.get_ylim(),
(df['positive'] > 0).apply(lambda x: int(x)).values[np.newaxis],
cmap=cmap, alpha=0.3)
fig.canvas.draw()
amp_slider.on_changed(sliders_on_changed)
freq_slider.on_changed(sliders_on_changed)
# Add a button for resetting the parameters
reset_button_ax = fig.add_axes([0.8, 0.025, 0.1, 0.04])
reset_button = Button(reset_button_ax, 'Reset', color=axis_color, hovercolor='0.975')
def reset_button_on_clicked(mouse_event):
freq_slider.reset()
amp_slider.reset()
reset_button.on_clicked(reset_button_on_clicked)
# Add a set of radio buttons for changing color
color_radios_ax = fig.add_axes([0.025, 0.5, 0.15, 0.15], facecolor=axis_color)
color_radios = RadioButtons(color_radios_ax, ('red', 'blue', 'green'), active=0)
def color_radios_on_clicked(label):
line.set_color(label)
fig.canvas.draw_idle()
color_radios.on_clicked(color_radios_on_clicked)
plt.show()