Jaewon Lee
Jaewon Lee

Reputation: 33

Using matplotlib Slider to create an interactive plot with different non-equally spaced parameters

I've been working with a set of data that has 4 input dimensions and 1 output. I want to visualize the data in 3D with 2 inputs fixed. At the same time, I want to adjust the 2 fixed inputs with sliders widget to see the graph change in real time. I used a neural network and I have all the output data but no simple funtion to generate the output data. (for example, for input size of 5*5*5*5 I have all 625 output data points)

I've been thinking about using sliders, but the widget seems to use fixed input intervals.

Below is the example code of the slider widget.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons

fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
t = np.arange(0.0, 1.0, 0.001)
a0 = 5
f0 = 3
delta_f = 5.0
s = a0*np.sin(2*np.pi*f0*t)
l, = plt.plot(t, s, lw=2, color='red')
plt.axis([0, 1, -10, 10])

axcolor = 'lightgoldenrodyellow'
axfreq = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor=axcolor)
axamp = plt.axes([0.25, 0.15, 0.65, 0.03], facecolor=axcolor)

sfreq = Slider(axfreq, 'Freq', 0.1, 30.0, valinit=f0, valstep=delta_f)
samp = Slider(axamp, 'Amp', 0.1, 10.0, valinit=a0)


def update(val):
    amp = samp.val
    freq = sfreq.val
    l.set_ydata(amp*np.sin(2*np.pi*freq*t))
    fig.canvas.draw_idle()
sfreq.on_changed(update)
samp.on_changed(update)

plt.show()

In this example, valstep is used to change the values with the sliders, and as the frequency and the amplitude change, it calculates corresponding outputs again with the given function and shows. But I want to do the same with frequency and amplitude that are not equally spaced (not same step size) and with all the output precalculated with given frequency and amplitudes. If I can somehow figure out how to do this, I can apply this to my work where the only difference is the 3D plot.

Thank you very much.

Upvotes: 1

Views: 2889

Answers (1)

Reblochon Masque
Reblochon Masque

Reputation: 36662

You could pass the value returned by the slider, to calculate a new value used as a parameter to your graph.

Alternatively, you could use a mapping of the values from the sliders to the value you want to use.

an (arguably contrived) example with functions that calculate and use a new value from the slider value:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons

import math

fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
t = np.arange(0.0, 1.0, 0.001)
a0 = 5
f0 = 3
delta_f = 5.0
s = a0 * np.sin(2 * np.pi * f0 * t)
l, = plt.plot(t, s, lw=2, color='red')
plt.axis([0, 1, -10, 10])

axcolor = 'lightgoldenrodyellow'
axfreq = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor=axcolor)
axamp = plt.axes([0.25, 0.15, 0.65, 0.03], facecolor=axcolor)

sfreq = Slider(axfreq, 'Freq', 0.1, 30.0, valinit=f0) #, valstep=delta_f)
samp = Slider(axamp, 'Amp', 0.1, 10.0, valinit=a0)


def get_amp_val(val):
    return math.exp(val)       # replace with a meaningful transformation of your parameters

def get_freq_val(val):
    return math.log(val)       # replace with a meaningful transformation of your parameters


def update(val):
    amp = get_amp_val(samp.val)      # call a transform on the slider value
    freq = get_freq_val(sfreq.val)   # call a transform on the slider value
    l.set_ydata(amp * np.sin(2 * np.pi * freq * t))
    fig.canvas.draw_idle()

sfreq.on_changed(update)
samp.on_changed(update)

plt.show()

using a mapping:

get_amp_val = {k, v for v, k in zip(values_you_want_to_use, slider_returned_values)}

def update(val):
    amp = get_amp_val[samp.val]      # retrieves the value mapped to the slider value
    ...

Upvotes: 1

Related Questions