diff --git a/lib/matplotlib/tests/test_widgets.py b/lib/matplotlib/tests/test_widgets.py
index 71ebd176f0b9..9964f2e9aab6 100644
--- a/lib/matplotlib/tests/test_widgets.py
+++ b/lib/matplotlib/tests/test_widgets.py
@@ -418,6 +418,45 @@ def test_slider_valmin_valmax():
     assert slider.val == slider.valmax
 
 
+def test_slider_set_limits():
+    fig, ax = plt.subplots()
+    slider = widgets.Slider(ax=ax, label='', valmin=10.0, valmax=40.0,
+                            valinit=15.0)
+    slider.set_limits(vmin=10, vmax=50)
+    assert slider.valinit == 15
+    assert slider.valmax == 50
+    assert slider.valmin == 10
+
+    slider = widgets.Slider(ax=ax, label='', valmin=10.0, valmax=40.0,
+                            valinit=15.0)
+    slider.set_limits(vmin=20, vmax=40)
+    assert slider.valinit == 20
+    assert slider.valmax == 40
+    assert slider.valmin == 20
+
+    slider = widgets.Slider(ax=ax, label='', valmin=10.0, valmax=40.0,
+                            valinit=15.0)
+    slider.val = 20
+    slider.set_limits(vmin=30, vmax=50)
+    assert slider.val == 30
+    assert slider.valmax == 50
+    assert slider.valmin == 30
+
+    slider = widgets.Slider(ax=ax, label='', valmin=10.0, valmax=40.0,
+                            valinit=15.0)
+    slider.val = 20
+    slider.set_limits(vmin=1, vmax=7)
+    assert slider.val == 7
+    assert slider.valmax == 7
+    assert slider.valmin == 1
+
+    slider = widgets.Slider(ax=ax, label='', valmin=10.0, valmax=40.0,
+                            valinit=15.0)
+    slider.set_limits()
+    assert slider.valmax == 40
+    assert slider.valmin == 10
+
+
 def test_slider_valstep_snapping():
     fig, ax = plt.subplots()
     slider = widgets.Slider(ax=ax, label='', valmin=0.0, valmax=24.0,
diff --git a/lib/matplotlib/widgets.py b/lib/matplotlib/widgets.py
index a199e45d4018..2e38e1787c77 100644
--- a/lib/matplotlib/widgets.py
+++ b/lib/matplotlib/widgets.py
@@ -306,6 +306,19 @@ def reset(self):
         if self.val != self.valinit:
             self.set_val(self.valinit)
 
+    def set_limits(self, vmin=None, vmax=None):
+        """Update the limits of the slider."""
+        if vmin is None and vmax is None:
+            return
+        if vmin is not None:
+            self.valmin = vmin
+        if vmax is not None:
+            self.valmax = vmax
+        if self.orientation == 'vertical':
+            self.ax.set_ylim((self.valmin, self.valmax))
+        else:
+            self.ax.set_xlim((self.valmin, self.valmax))
+
 
 class Slider(SliderBase):
     """
@@ -583,6 +596,18 @@ def on_changed(self, func):
         """
         return self._observers.connect('changed', lambda val: func(val))
 
+    def set_limits(self, vmin=None, vmax=None):
+        """Update the limits of the slider."""
+        super().set_limits(vmin=vmin, vmax=vmax)
+        self.val = self._value_in_bounds(self.val)
+        # if we reset the slider after updating the limits then we should have
+        # the proper valinit value
+        self.valinit = self._value_in_bounds(self.valinit)
+        if self.orientation == 'vertical':
+            self.hline.set_ydata(self.valinit)
+        else:
+            self.vline.set_xdata(self.valinit)
+
 
 class RangeSlider(SliderBase):
     """