Skip to content

Commit 88705a5

Browse files
merge master
1 parent d10bbce commit 88705a5

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed

doc/source/whatsnew/v0.25.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ including other versions of pandas.
1818

1919
Other Enhancements
2020
^^^^^^^^^^^^^^^^^^
21-
21+
- :func:`DataFrame.plot` keywords ``logy``, ``logx`` and ``loglog`` can now accept the value ``sym`` for symlog scaling. (:issue:`24867`)
2222
- Indexing of ``DataFrame`` and ``Series`` now accepts zerodim ``np.ndarray`` (:issue:`24919`)
2323
- :meth:`Timestamp.replace` now supports the ``fold`` argument to disambiguate DST transition times (:issue:`25017`)
2424
- :meth:`DataFrame.at_time` and :meth:`Series.at_time` now support :meth:`datetime.time` objects with timezones (:issue:`24043`)

pandas/plotting/_core.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -308,10 +308,20 @@ def _setup_subplots(self):
308308

309309
axes = _flatten(axes)
310310

311-
if self.logx or self.loglog:
311+
valid_log = {False, True, 'sym', None}
312+
input_log = {self.logx, self.logy, self.loglog}
313+
if input_log - valid_log:
314+
raise ValueError("Valid inputs are boolean, None and 'sym'.")
315+
316+
if self.logx is True or self.loglog is True:
312317
[a.set_xscale('log') for a in axes]
313-
if self.logy or self.loglog:
318+
elif self.logx == 'sym' or self.loglog == 'sym':
319+
[a.set_xscale('symlog') for a in axes]
320+
321+
if self.logy is True or self.loglog is True:
314322
[a.set_yscale('log') for a in axes]
323+
elif self.logy == 'sym' or self.loglog == 'sym':
324+
[a.set_yscale('symlog') for a in axes]
315325

316326
self.fig = fig
317327
self.axes = axes

pandas/tests/plotting/test_frame.py

+28
Original file line numberDiff line numberDiff line change
@@ -231,14 +231,42 @@ def test_plot_xy(self):
231231
@pytest.mark.slow
232232
def test_logscales(self):
233233
df = DataFrame({'a': np.arange(100)}, index=np.arange(100))
234+
234235
ax = df.plot(logy=True)
235236
self._check_ax_scales(ax, yaxis='log')
237+
assert ax.get_yscale() == 'log'
238+
239+
ax = df.plot(logy='sym')
240+
self._check_ax_scales(ax, yaxis='symlog')
241+
assert ax.get_yscale() == 'symlog'
236242

237243
ax = df.plot(logx=True)
238244
self._check_ax_scales(ax, xaxis='log')
245+
assert ax.get_xscale() == 'log'
246+
247+
ax = df.plot(logx='sym')
248+
self._check_ax_scales(ax, xaxis='symlog')
249+
assert ax.get_xscale() == 'symlog'
239250

240251
ax = df.plot(loglog=True)
241252
self._check_ax_scales(ax, xaxis='log', yaxis='log')
253+
assert ax.get_xscale() == 'log'
254+
assert ax.get_yscale() == 'log'
255+
256+
ax = df.plot(loglog='sym')
257+
self._check_ax_scales(ax, xaxis='symlog', yaxis='symlog')
258+
assert ax.get_xscale() == 'symlog'
259+
assert ax.get_yscale() == 'symlog'
260+
261+
@pytest.mark.parametrize("wrong_input", ["sm", "symlog"])
262+
@pytest.mark.parametrize("input_param", ["logx", "logy", "loglog"])
263+
def test_invalid_logscale(self, wrong_input, input_param):
264+
# GH: 24867
265+
df = DataFrame({'a': np.arange(100)}, index=np.arange(100))
266+
267+
msg = "Valid inputs are boolean, None and 'sym'."
268+
with pytest.raises(ValueError, match=msg):
269+
df.plot(**{input_param: wrong_input})
242270

243271
@pytest.mark.slow
244272
def test_xcompat(self):

0 commit comments

Comments
 (0)