Skip to content

Commit c63d623

Browse files
committed
ENH: horizontal bar plot working, change default rotation for bar plots
1 parent f2d32c8 commit c63d623

File tree

4 files changed

+52
-17
lines changed

4 files changed

+52
-17
lines changed

pandas/core/series.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2448,6 +2448,7 @@ def f(x):
24482448
Series.plot = _gfx.plot_series
24492449
Series.hist = _gfx.hist_series
24502450

2451+
# Put here, otherwise monkey-patching in methods fails
24512452

24522453
class TimeSeries(Series):
24532454
pass

pandas/src/inference.pyx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ def infer_dtype(object _values):
6060
if is_datetime_array(values):
6161
return 'datetime'
6262

63+
elif is_date(val):
64+
if is_date_array(values):
65+
return 'date'
66+
6367
elif util.is_float_object(val):
6468
if is_float_array(values):
6569

@@ -88,6 +92,9 @@ def infer_dtype_list(list values):
8892
cdef inline bint is_datetime(object o):
8993
return PyDateTime_Check(o)
9094

95+
cdef inline bint is_date(object o):
96+
return PyDate_Check(o)
97+
9198
def is_bool_array(ndarray values):
9299
cdef:
93100
Py_ssize_t i, n = len(values)

pandas/tests/test_tseries.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,9 @@ def test_unicode(self):
349349
def test_datetime(self):
350350
pass
351351

352+
def test_date(self):
353+
pass
354+
352355
def test_to_object_array_tuples(self):
353356
r = (5,6)
354357
values = [r]

pandas/tools/plotting.py

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,11 @@ class MPLPlot(object):
5353
data :
5454
5555
"""
56+
_default_rot = 0
57+
5658
def __init__(self, data, kind=None, by=None, subplots=False, sharex=True,
5759
sharey=False, use_index=True,
58-
figsize=None, grid=True, legend=True, rot=30,
60+
figsize=None, grid=True, legend=True, rot=None,
5961
ax=None, fig=None, title=None,
6062
xlim=None, ylim=None,
6163
xticks=None, yticks=None,
@@ -97,6 +99,7 @@ def __init__(self, data, kind=None, by=None, subplots=False, sharex=True,
9799
self._setup_subplots()
98100
self._make_plot()
99101
self._post_plot_logic()
102+
self._adorn_subplots()
100103

101104
def draw(self):
102105
self.plt.draw_if_interactive()
@@ -235,12 +238,17 @@ def _post_plot_logic(self):
235238

236239

237240
class BarPlot(MPLPlot):
241+
_default_rot = {'bar' : 90, 'barh' : 0}
238242

239243
def __init__(self, data, **kwargs):
240244
self.stacked = kwargs.pop('stacked', False)
245+
self.ax_pos = np.arange(len(data)) + 0.25
241246
MPLPlot.__init__(self, data, **kwargs)
242247

243248
def _args_adjust(self):
249+
if self.rot is None:
250+
self.rot = self._default_rot[self.kind]
251+
244252
if self.fontsize is None:
245253
if len(self.data) < 10:
246254
self.fontsize = 12
@@ -264,7 +272,7 @@ def _make_plot(self):
264272
df = self.data
265273

266274
N, K = df.shape
267-
xinds = np.arange(N) + 0.25
275+
268276
colors = 'rgbyk'
269277
rects = []
270278
labels = []
@@ -273,47 +281,62 @@ def _make_plot(self):
273281

274282
bar_f = self.bar_f
275283

276-
prior = np.zeros(N)
284+
pos_prior = neg_prior = np.zeros(N)
277285
for i, col in enumerate(df.columns):
278286
empty = df[col].count() == 0
279287
y = df[col].values if not empty else np.zeros(len(df))
280288

281289
if self.subplots:
282290
ax = self.axes[i]
283-
rect = bar_f(ax, xinds, y, 0.5, start=prior,
291+
rect = bar_f(ax, self.ax_pos, y, 0.5, start=pos_prior,
284292
linewidth=1, **self.kwds)
285293
ax.set_title(col)
286294
elif self.stacked:
287-
rect = bar_f(ax, xinds, y, 0.5, start=prior,
295+
mask = y > 0
296+
start = np.where(mask, pos_prior, neg_prior)
297+
rect = bar_f(ax, self.ax_pos, y, 0.5, start=start,
288298
color=colors[i % len(colors)],
289299
label=str(col), linewidth=1,
290300
**self.kwds)
291-
prior = y + prior
301+
pos_prior = pos_prior + np.where(mask, y, 0)
302+
neg_prior = neg_prior + np.where(mask, 0, y)
292303
else:
293-
rect = bar_f(ax, xinds + i * 0.75 / K, y, 0.75 / K,
304+
rect = bar_f(ax, self.ax_pos + i * 0.75 / K, y, 0.75 / K,
294305
start=np.zeros(N), label=str(col),
295306
color=colors[i % len(colors)],
296307
**self.kwds)
297308
rects.append(rect)
298309
labels.append(col)
299310

300-
ax.set_xlim([xinds[0] - 0.25, xinds[-1] + 1])
301-
ax.set_xticks(xinds + 0.375)
302-
ax.set_xticklabels([_stringify(key) for key in df.index],
303-
rotation=self.rot,
304-
fontsize=self.fontsize)
305-
306311
if self.legend and not self.subplots:
307312
patches =[r[0] for r in rects]
308313

309314
# Legend to the right of the plot
310315
# ax.legend(patches, labels, bbox_to_anchor=(1.05, 1),
311316
# loc=2, borderaxespad=0.)
317+
# self.fig.subplots_adjust(right=0.80)
312318

313319
ax.legend(patches, labels, loc='best')
314320

315-
self.fig.subplots_adjust(top=0.8, right=0.80)
316321

322+
self.fig.subplots_adjust(top=0.8)
323+
324+
def _post_plot_logic(self):
325+
for ax in self.axes:
326+
str_index = [_stringify(key) for key in self.data.index]
327+
if self.kind == 'bar':
328+
ax.set_xlim([self.ax_pos[0] - 0.25, self.ax_pos[-1] + 1])
329+
ax.set_xticks(self.ax_pos + 0.375)
330+
ax.set_xticklabels(str_index, rotation=self.rot,
331+
fontsize=self.fontsize)
332+
ax.axhline(0, color='k', linestyle='--')
333+
else:
334+
# horizontal bars
335+
ax.set_ylim([self.ax_pos[0] - 0.25, self.ax_pos[-1] + 1])
336+
ax.set_yticks(self.ax_pos + 0.375)
337+
ax.set_yticklabels(str_index, rotation=self.rot,
338+
fontsize=self.fontsize)
339+
ax.axvline(0, color='k', linestyle='--')
317340

318341
class BoxPlot(MPLPlot):
319342
pass
@@ -325,7 +348,7 @@ class HistPlot(MPLPlot):
325348

326349
def plot_frame(frame=None, subplots=False, sharex=True, sharey=False,
327350
use_index=True,
328-
figsize=None, grid=True, legend=True, rot=30,
351+
figsize=None, grid=True, legend=True, rot=None,
329352
ax=None, title=None,
330353
xlim=None, ylim=None,
331354
xticks=None, yticks=None,
@@ -843,8 +866,9 @@ def _subplots(nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True,
843866
reload(fr)
844867
from pandas.core.frame import DataFrame
845868

846-
data = DataFrame([[3, 6], [4, 8], [4, 9], [4, 9], [2, 5]],
847-
columns=['A', 'B'])
869+
data = DataFrame([[3, 6, -5], [4, 8, 2], [4, 9, -6],
870+
[4, 9, -3], [2, 5, -1]],
871+
columns=['A', 'B', 'C'])
848872
data.plot(kind='barh', stacked=True)
849873

850874
plt.show()

0 commit comments

Comments
 (0)