Repository: pandas-dev/pandas

Issue:
BUG: barplot with log=True not working for values smaller than 1
```
s = pd.Series([0.1, 0.01, 0.001], index=['a', 'b', 'c'])
s.plot(kind='bar', log=True)
```

gives:

```
TypeError                                 Traceback (most recent call last)
<ipython-input-13-75b989d29042> in <module>()
      1 s = pd.Series([0.1, 0.01, 0.001], index=['a', 'b', 'c'])
----> 2 s.plot(kind='bar', log=True)

C:\Anaconda\lib\site-packages\pandas\tools\plotting.pyc in plot_series(data, kind, ax, figsize, use_index, title, grid, legend, style, logx, logy, loglog, xticks, yticks, xlim, ylim, rot, fontsize, colormap, table, yerr, xerr, label, secondary_y, **kwds)
   2517                  yerr=yerr, xerr=xerr,
   2518                  label=label, secondary_y=secondary_y,
-> 2519                  **kwds)
   2520 
   2521 

C:\Anaconda\lib\site-packages\pandas\tools\plotting.pyc in _plot(data, x, y, subplots, ax, kind, **kwds)
   2323         plot_obj = klass(data, subplots=subplots, ax=ax, kind=kind, **kwds)
   2324 
-> 2325     plot_obj.generate()
   2326     plot_obj.draw()
   2327     return plot_obj.result

C:\Anaconda\lib\site-packages\pandas\tools\plotting.pyc in generate(self)
    921         self._compute_plot_data()
    922         self._setup_subplots()
--> 923         self._make_plot()
    924         self._add_table()
    925         self._make_legend()

C:\Anaconda\lib\site-packages\pandas\tools\plotting.pyc in _make_plot(self)
   1884                 w = self.bar_width / K
   1885                 rect = bar_f(ax, self.ax_pos + (i + 0.5) * w, y, w,
-> 1886                              start=start, label=label, **kwds)
   1887             self._add_legend_handle(rect, label, index=i)
   1888 

C:\Anaconda\lib\site-packages\pandas\tools\plotting.pyc in f(ax, x, y, w, start, **kwds)
   1823         if self.kind == 'bar':
   1824             def f(ax, x, y, w, start=None, **kwds):
-> 1825                 start = start + self.bottom
   1826                 return ax.bar(x, y, w, bottom=start,log=self.log, **kwds)
   1827         elif self.kind == 'barh':

TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
```

This was working in 0.14.1



Discussion:
@sinhrks if you can have a look. If I revert the lines touching the handling of `bottom` in this commit https://github.com/pydata/pandas/commit/53cc1b7447ced5fde96d887af414f801b2913494 (around lines 1700-1800 in plotting.py) it works for me (but not sure if that would be the best fix)


Resolving patch:
diff --git a/pandas/tools/plotting.py b/pandas/tools/plotting.py
--- a/pandas/tools/plotting.py
+++ b/pandas/tools/plotting.py
@@ -1824,11 +1824,12 @@ def _get_plot_function(self):
         if self.kind == 'bar':
             def f(ax, x, y, w, start=None, **kwds):
                 start = start + self.bottom
-                return ax.bar(x, y, w, bottom=start,log=self.log, **kwds)
+                return ax.bar(x, y, w, bottom=start, log=self.log, **kwds)
         elif self.kind == 'barh':
+
             def f(ax, x, y, w, start=None, log=self.log, **kwds):
                 start = start + self.left
-                return ax.barh(x, y, w, left=start, **kwds)
+                return ax.barh(x, y, w, left=start, log=self.log, **kwds)
         else:
             raise ValueError("BarPlot kind must be either 'bar' or 'barh'")
 
@@ -1836,9 +1837,6 @@ def f(ax, x, y, w, start=None, log=self.log, **kwds):
 
     def _make_plot(self):
         import matplotlib as mpl
-        # mpl decided to make their version string unicode across all Python
-        # versions for mpl >= 1.3 so we have to call str here for python 2
-        mpl_le_1_2_1 = str(mpl.__version__) <= LooseVersion('1.2.1')
 
         colors = self._get_colors()
         ncolors = len(colors)
@@ -1862,11 +1860,8 @@ def _make_plot(self):
                 kwds['ecolor'] = mpl.rcParams['xtick.color']
 
             start = 0
-            if self.log:
+            if self.log and (y >= 1).all():
                 start = 1
-                if any(y < 1):
-                    # GH3254
-                    start = 0 if mpl_le_1_2_1 else None
 
             if self.subplots:
                 w = self.bar_width / 2


Test patch:
diff --git a/pandas/tests/test_graphics.py b/pandas/tests/test_graphics.py
--- a/pandas/tests/test_graphics.py
+++ b/pandas/tests/test_graphics.py
@@ -592,6 +592,26 @@ def test_bar_log(self):
 
         ax = Series([200, 500]).plot(log=True, kind='bar')
         assert_array_equal(ax.yaxis.get_ticklocs(), expected)
+        tm.close()
+
+        ax = Series([200, 500]).plot(log=True, kind='barh')
+        assert_array_equal(ax.xaxis.get_ticklocs(), expected)
+        tm.close()
+
+        # GH 9905
+        expected = np.array([1.0e-03, 1.0e-02, 1.0e-01, 1.0e+00])
+
+        if not self.mpl_le_1_2_1:
+            expected = np.hstack((1.0e-04, expected, 1.0e+01))
+
+        ax = Series([0.1, 0.01, 0.001]).plot(log=True, kind='bar')
+        assert_array_equal(ax.get_ylim(), (0.001, 0.10000000000000001))
+        assert_array_equal(ax.yaxis.get_ticklocs(), expected)
+        tm.close()
+
+        ax = Series([0.1, 0.01, 0.001]).plot(log=True, kind='barh')
+        assert_array_equal(ax.get_xlim(), (0.001, 0.10000000000000001))
+        assert_array_equal(ax.xaxis.get_ticklocs(), expected)
 
     @slow
     def test_bar_ignore_index(self):