diff --git a/doc/api/api_changes/2017-07-03-DS-logscale_masked.rst b/doc/api/api_changes/2017-07-03-DS-logscale_masked.rst
new file mode 100644
index 000000000000..5de845f90a7c
--- /dev/null
+++ b/doc/api/api_changes/2017-07-03-DS-logscale_masked.rst
@@ -0,0 +1,8 @@
+Default behavior of log scales changed to mask <= 0 values
+``````````````````````````````````````````````````````````
+
+Calling `matplotlib.axes.Axes.set_xscale` or `matplotlib.axes.Axes.set_yscale`
+now uses 'mask' as the default method to handle invalid values (as opposed to
+'clip'). This means that any values <= 0 on a log scale will not be shown.
+
+Previously they were clipped to a very small number and shown.
diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py
index bfbf81bc67be..85877358e754 100644
--- a/lib/matplotlib/axes/_axes.py
+++ b/lib/matplotlib/axes/_axes.py
@@ -1578,7 +1578,6 @@ def semilogx(self, *args, **kwargs):
self.cla()
d = {'basex': kwargs.pop('basex', 10),
'subsx': kwargs.pop('subsx', None),
- 'nonposx': kwargs.pop('nonposx', 'mask'),
}
self.set_xscale('log', **d)
@@ -1629,7 +1628,6 @@ def semilogy(self, *args, **kwargs):
self.cla()
d = {'basey': kwargs.pop('basey', 10),
'subsy': kwargs.pop('subsy', None),
- 'nonposy': kwargs.pop('nonposy', 'mask'),
}
self.set_yscale('log', **d)
b = self._hold
@@ -2753,6 +2751,10 @@ def errorbar(self, x, y, yerr=None, xerr=None,
%(Line2D)s
+ Notes
+ -----
+ Error bars with negative values will not be shown when plotted on a
+ logarithmic axis.
"""
kwargs = cbook.normalize_kwargs(kwargs, _alias_map)
# anything that comes in as 'None', drop so the default thing
diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py
index 3dab3749ebf0..e5f189c94b62 100644
--- a/lib/matplotlib/axes/_base.py
+++ b/lib/matplotlib/axes/_base.py
@@ -2961,10 +2961,10 @@ def set_xscale(self, value, **kwargs):
matplotlib.scale.LogisticTransform : logit transform
"""
- # If the scale is being set to log, clip nonposx to prevent headaches
+ # If the scale is being set to log, mask nonposx to prevent headaches
# around zero
if value.lower() == 'log' and 'nonposx' not in kwargs:
- kwargs['nonposx'] = 'clip'
+ kwargs['nonposx'] = 'mask'
g = self.get_shared_x_axes()
for ax in g.get_siblings(self):
@@ -3255,10 +3255,10 @@ def set_yscale(self, value, **kwargs):
matplotlib.scale.LogisticTransform : logit transform
"""
- # If the scale is being set to log, clip nonposy to prevent headaches
+ # If the scale is being set to log, mask nonposy to prevent headaches
# around zero
if value.lower() == 'log' and 'nonposy' not in kwargs:
- kwargs['nonposy'] = 'clip'
+ kwargs['nonposy'] = 'mask'
g = self.get_shared_y_axes()
for ax in g.get_siblings(self):
diff --git a/lib/matplotlib/tests/baseline_images/test_axes/log_scales.png b/lib/matplotlib/tests/baseline_images/test_axes/log_scales.png
index 876b47caedb6..9e68e62fd75d 100644
Binary files a/lib/matplotlib/tests/baseline_images/test_axes/log_scales.png and b/lib/matplotlib/tests/baseline_images/test_axes/log_scales.png differ
diff --git a/lib/matplotlib/tests/baseline_images/test_axes/log_scales.svg b/lib/matplotlib/tests/baseline_images/test_axes/log_scales.svg
index 2e63e7be1870..596ba00f9b67 100644
--- a/lib/matplotlib/tests/baseline_images/test_axes/log_scales.svg
+++ b/lib/matplotlib/tests/baseline_images/test_axes/log_scales.svg
@@ -27,8 +27,7 @@ z
" style="fill:#ffffff;"/>
-
+" id="m368fc901b1" style="stroke:#000000;stroke-width:0.5;"/>
-
+
+" id="mc63e59a608" style="stroke:#000000;stroke-width:0.5;"/>
-
+
@@ -142,6 +141,7 @@ Q 56.59375 19.140625 48.40625 8.859375
Q 40.234375 -1.421875 26.421875 -1.421875
Q 22.703125 -1.421875 18.890625 -0.6875
Q 15.09375 0.046875 10.984375 1.515625
+z
M 30.609375 32.421875
Q 37.25 32.421875 41.125 36.953125
Q 45.015625 41.5 45.015625 49.421875
@@ -151,6 +151,7 @@ Q 23.96875 66.40625 20.09375 61.84375
Q 16.21875 57.28125 16.21875 49.421875
Q 16.21875 41.5 20.09375 36.953125
Q 23.96875 32.421875 30.609375 32.421875
+z
" id="DejaVuSans-39"/>
@@ -181,12 +184,12 @@ Q 19.53125 74.21875 31.78125 74.21875
-
+
-
+
@@ -215,12 +218,12 @@ z
-
+
-
+
@@ -248,6 +251,7 @@ Q 53.21875 48.921875 51.53125 44.890625
Q 49.859375 40.875 45.40625 35.40625
Q 44.1875 33.984375 37.640625 27.21875
Q 31.109375 20.453125 19.1875 8.296875
+z
" id="DejaVuSans-32"/>
@@ -261,176 +265,176 @@ Q 31.109375 20.453125 19.1875 8.296875
+" id="mce6b333cae" style="stroke:#000000;stroke-width:0.5;"/>
-
+
+" id="m8d518e7239" style="stroke:#000000;stroke-width:0.5;"/>
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -441,20 +445,20 @@ L 0 2
+" id="m556f96d829" style="stroke:#000000;stroke-width:0.5;"/>
-
+
+" id="m27e32ca04a" style="stroke:#000000;stroke-width:0.5;"/>
-
+
@@ -509,12 +513,12 @@ z
-
+
-
+
@@ -530,12 +534,12 @@ z
-
+
-
+
@@ -553,104 +557,104 @@ z
+" id="mb12535d6a8" style="stroke:#000000;stroke-width:0.5;"/>
-
+
+" id="m8a2e629618" style="stroke:#000000;stroke-width:0.5;"/>
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -658,7 +662,7 @@ L -2 0
-
+
diff --git a/lib/matplotlib/tests/baseline_images/test_scale/logscale_mask.png b/lib/matplotlib/tests/baseline_images/test_scale/logscale_mask.png
new file mode 100644
index 000000000000..0f142c315729
Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_scale/logscale_mask.png differ
diff --git a/lib/matplotlib/tests/test_scale.py b/lib/matplotlib/tests/test_scale.py
index 45ec7557ee88..e23ba8fcdd51 100644
--- a/lib/matplotlib/tests/test_scale.py
+++ b/lib/matplotlib/tests/test_scale.py
@@ -52,3 +52,16 @@ def test_logscale_subs():
ax.set_yscale('log', subsy=np.array([2, 3, 4]))
# force draw
fig.canvas.draw()
+
+
+@image_comparison(baseline_images=['logscale_mask'], remove_text=True,
+ extensions=['png'])
+def test_logscale_mask():
+ # Check that zero values are masked correctly on log scales.
+ # See github issue 8045
+ xs = np.linspace(0, 50, 1001)
+
+ fig, ax = plt.subplots()
+ ax.plot(np.exp(-xs**2))
+ fig.canvas.draw()
+ ax.set(yscale="log")