Я использую python/pandas dataframe для построения гистограммы, но мне не удалось настроить ширину полосы, используя массив или столбцы df, например:
df.plot.bar(ax=axes[i], width=df.width, stacked=True, color=colors[i], logy=logy)
где df.width
- это столбец в моем кадре данных. Трассировки стека:
File "/usr/local/lib/python2.7/dist-packages/pandas/plotting/_core.py", line 3090, in bar
return self(kind='bar', x=x, y=y, **kwds)
File "/usr/local/lib/python2.7/dist-packages/pandas/plotting/_core.py", line 2941, in __call__
sort_columns=sort_columns, **kwds)
File "/usr/local/lib/python2.7/dist-packages/pandas/plotting/_core.py", line 1977, in plot_frame
**kwds)
File "/usr/local/lib/python2.7/dist-packages/pandas/plotting/_core.py", line 1804, in _plot
plot_obj.generate()
File "/usr/local/lib/python2.7/dist-packages/pandas/plotting/_core.py", line 267, in generate
self._post_plot_logic(ax, self.data)
File "/usr/local/lib/python2.7/dist-packages/pandas/plotting/_core.py", line 1276, in _post_plot_logic
e_edge = self.ax_pos[-1] + 0.25 + self.bar_width + self.lim_offset
File "/usr/local/lib/python2.7/dist-packages/pandas/core/series.py", line 767, in __getitem__
result = self.index.get_value(self, key)
File "/usr/local/lib/python2.7/dist-packages/pandas/core/indexes/numeric.py", line 358, in get_value
loc = self.get_loc(k)
File "/usr/local/lib/python2.7/dist-packages/pandas/core/indexes/numeric.py", line 419, in get_loc
tolerance=tolerance)
File "/usr/local/lib/python2.7/dist-packages/pandas/core/indexes/base.py", line 3080, in get_loc
return self._engine.get_loc(self._maybe_cast_indexer(key))
File "pandas/_libs/index.pyx", line 140, in pandas._libs.index.IndexEngine.get_loc
File "pandas/_libs/index.pyx", line 162, in pandas._libs.index.IndexEngine.get_loc
File "pandas/_libs/hashtable_class_helper.pxi", line 379, in pandas._libs.hashtable.Float64HashTable.get_item
File "pandas/_libs/hashtable_class_helper.pxi", line 385, in pandas._libs.hashtable.Float64HashTable.get_item
KeyError: -1.0
Вместо использования столбца df я попытался использовать список, но у меня возникла проблема:
wl = df.width.tolist()
df.plot.bar(ax=axes[i], width=wl, stacked=True, color=colors[i], logy=logy)
Трассировки стека:
File "/usr/local/lib/python2.7/dist-packages/pandas/plotting/_core.py", line 3090, in bar
return self(kind='bar', x=x, y=y, **kwds)
File "/usr/local/lib/python2.7/dist-packages/pandas/plotting/_core.py", line 2941, in __call__
sort_columns=sort_columns, **kwds)
File "/usr/local/lib/python2.7/dist-packages/pandas/plotting/_core.py", line 1977, in plot_frame
**kwds)
File "/usr/local/lib/python2.7/dist-packages/pandas/plotting/_core.py", line 1802, in _plot
plot_obj = klass(data, subplots=subplots, ax=ax, kind=kind, **kwds)
File "/usr/local/lib/python2.7/dist-packages/pandas/plotting/_core.py", line 1185, in __init__
self.tickoffset = self.bar_width * pos
TypeError: can't multiply sequence by non-int of type 'float'
Я ценю любую помощь. Ниже минимального кода для воспроизведения проблемы:
import pandas as pd
import matplotlib.pyplot as plt
fig, ax = plt.subplots(nrows=1, ncols=1, sharex=True)
my_dict = {'width': {0.0: 3.0, 3.0: 2.0, 5.0: 1.0}, 'kbps1': {0.0: 10.0, 3.0: 20.0, 5.0: 30}, 'kbps2': {0.0: 5.0, 3.0: 10.0, 5.0: 15.0}, 'kbps3': {0.0: 3.0, 3.0: 10.0, 5.0: 10.0}}
ndf = pd.DataFrame(my_dict)
wl = ndf.width.tolist()
ndf = ndf[['kbps1','kbps2','kbps3']]
# Problem
ndf.plot.bar(ax=ax, width=wl, stacked=True)
# Working with scalar
ndf.plot.bar(ax=ax, width=1.0, stacked=True)
Я исправил проблему, используя plt.bar вместо df.plot.bar. Вот решение:
fig, ax = plt.subplots(nrows=1, ncols=1)
my_dict = {'width': {0.0: 3.0, 3.0: 2.0, 5.0: 1.0}, 'kbps1': {0.0: 10.0, 3.0: 20.0, 5.0: 30}, 'kbps2': {0.0: 5.0, 3.0: 10.0, 5.0: 15.0}, 'kbps3': {0.0: 3.0, 3.0: 10.0, 5.0: 10.0}}
ndf = pd.DataFrame(my_dict)
for c in ndf.drop(['width'], axis=1).columns:
ax.bar(ndf.index, ndf[c], align='edge', width=ndf.width)
Никакое представление о причине "ширины" в пандах не имеет такого отличного поведения.