I just implemented a slider in my plot which works great. (I used this example: http://matplotlib.org/examples/widgets/slider_demo.html) Now my question is if it is possible to make the slider logarithmic. My values range between 0 and 1 and I want to make changes from 0.01 to 0.02 and so on but also from 0.01 to 0.5. That is why I think a logarithmic scale would be nice. Also if this isn't doable with a slider do you then have other ideas how to implement this?
2 Answers
You can simply np.log()
the value of the slider. However then the label next to it would be incorrect. You need to manually set the text of valtext
of the slider to the log-value:
def update(val):
amp = np.log(slider.val)
slider.valtext.set_text(amp)

- 34,832
- 7
- 76
- 98
I know it's been few years but I think it still is useful. The previous answer is simple and straightforward but can be a problem with the inital values not correctly displayed for example. You can directly create a log slider by creating a new class inheriting from the matplotlib slider and edit the function that set the value like so :
from matplotlib.widgets import Slider
class Sliderlog(Slider):
"""Logarithmic slider.
Takes in every method and function of the matplotlib's slider.
Set slider to *val* visually so the slider still is lineat but display 10**val next to the slider.
Return 10**val to the update function (func)"""
def set_val(self, val):
xy = self.poly.xy
if self.orientation == 'vertical':
xy[1] = 0, val
xy[2] = 1, val
else:
xy[2] = val, 1
xy[3] = val, 0
self.poly.xy = xy
self.valtext.set_text(self.valfmt % 10**val) # Modified to display 10**val instead of val
if self.drawon:
self.ax.figure.canvas.draw_idle()
self.val = val
if not self.eventson:
return
for cid, func in self.observers.items():
func(10**val)
You use it the same way you use the slider but instead of call :
Slider(ax, label, valmin, valmax, valinit=0.5, valfmt='%1.2f', closedmin=True, closedmax=True, slidermin=None, slidermax=None, dragging=True, valstep=None, orientation='horizontal')
Just call :
Sliderlog(ax, label, valmin, valmax, valinit=0.5, valfmt='%1.2f', closedmin=True, closedmax=True, slidermin=None, slidermax=None, dragging=True, valstep=None, orientation='horizontal',
Be careful, if you want to have 10^3 as initial value you have to pass in valinit=3 not 10**3. Same for valmax and valmin. You can use log10(desired_value) if you can not easily type it.

- 41
- 1
-
I like the idea, but in the end this didn't quite work out for me. Empty `valfmt` is not handled and `observers` is deprecated in version 3.4. So this will not age well I think. But perhaps it could be improved. – Felix Jun 17 '21 at 13:27