LlamaD
LlamaD

Reputation: 442

Updating contour plot levels with matplotlib slider

I'm trying to change the values of the colour levels on a matplotlib filled contour plot using a slider. i.e contourf(x,y,z,np.linspace(a,b,n)) where the sliders would control a and b and would change the plot colour levels when a slider is moved. The following code takes column formatted data converts it to the form required by contourf and then the the sliders are implemented. This is what I've tried:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider

data=np.genfromtxt('file.dat',skip_header=1)
len=np.sqrt(data[:,0].size)
x=np.reshape(data[:,0],(len,len))       
y=np.reshape(data[:,1],(len,len))
z=np.reshape(data[:,3],(len,len))

l=plt.contourf(x,y,z,np.linspace(0,100,255))

axmax = plt.axes([0.25, 0.1, 0.65, 0.03])  #slider location and size
axmin  = plt.axes([0.25, 0.15, 0.65, 0.03])
smax = Slider(axmax, 'Max',0, 100, 50)      #slider properties
smin = Slider(axmin, 'Min', 0, 100, 0)

def update(val):
    l.levels(np.linspace(smin.val,smax.val,255))#changing levels of plot
    fig.canvas.draw_idle()                      #line that throws error
smax.on_changed(update)
smin.on_changed(update)

plt.show()

A large number of matplotlib errors are thrown when a slider is moved with the relevant one being 'TypeError:'numpy.ndarray' object is not callable' which is thrown by the line

fig.canvas.draw_idle()

Upvotes: 5

Views: 3638

Answers (1)

M4rtini
M4rtini

Reputation: 13539

The problem is that l.levels is a array, so you would have to change the values in this array. In my testing changing these values does not cause the plot to update. So another solution is to just clear the axis and redraw the plot.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider

data=np.random.random([25,4])
data = data*100
len=np.sqrt(data[:,0].size)
x=np.reshape(data[:,0],(len,len))       
y=np.reshape(data[:,1],(len,len))
z=np.reshape(data[:,3],(len,len))

l=plt.contourf(x,y,z,np.linspace(0,100,255))
contour_axis = plt.gca()

axmax = plt.axes([0.25, 0.1, 0.65, 0.03])  #slider location and size
axmin  = plt.axes([0.25, 0.15, 0.65, 0.03])
smax = Slider(axmax, 'Max',0, 100, 50)      #slider properties
smin = Slider(axmin, 'Min', 0, 100, 0)


def update(val):
    contour_axis.clear()
    contour_axis.contourf(x,y,z,np.linspace(smin.val,smax.val,255))
    plt.draw()                   
smax.on_changed(update)
smin.on_changed(update)

plt.show()

Upvotes: 4

Related Questions