Pandas: Bar plot x-axis is indexed as integers starting from 0 regardless of values of the index

Created on 4 Apr 2018  路  4Comments  路  Source: pandas-dev/pandas

Code Sample, a copy-pastable example if possible

index = np.linspace(1,10,10)
values = np.random.random(size=(10))
koe1 = pd.Series(values,index=index)

ax = koe1.plot(kind='bar')
ax.axvline(2.5,ls='--',color='black',lw=0.5)

Problem description

Vertical line is plotted between ticks 3 and 4. I would expect it to be plotted between ticks 2 and 3. If I plot the data as a line plot, then the vertical line is positioned as expected.

Expected Output

Output of pd.show_versions()

[paste the output of pd.show_versions() here below this line]

NSTALLED VERSIONS

commit: None
python: 3.6.4.final.0
python-bits: 64
OS: Windows
OS-release: 7
machine: AMD64
processor: Intel64 Family 6 Model 58 Stepping 9, GenuineIntel
byteorder: little
LC_ALL: None
LANG: en_US
LOCALE: None.None

pandas: 0.22.0
pytest: 3.3.2
pip: 9.0.1
setuptools: 38.4.0
Cython: 0.27.3
numpy: 1.14.0
scipy: 1.0.0
pyarrow: None
xarray: None
IPython: 6.2.1
sphinx: 1.6.6
patsy: 0.5.0
dateutil: 2.6.1
pytz: 2017.3
blosc: None
bottleneck: 1.2.1
tables: 3.4.2
numexpr: 2.6.4
feather: None
matplotlib: 2.1.2
openpyxl: 2.4.10
xlrd: 1.1.0
xlwt: 1.3.0
xlsxwriter: 1.0.2
lxml: 4.1.1
bs4: 4.6.0
html5lib: 1.0.1
sqlalchemy: 1.2.1
pymysql: None
psycopg2: None
jinja2: 2.10
s3fs: None
fastparquet: None
pandas_gbq: None
pandas_datareader: None

Usage Question

All 4 comments

I believe that the bars / ticks are always on the integers [0, n_bars). Take a look at ax.get_xticks().

So I think everything is functioning as expected.

Thanks for the suggestion. I'm probably using the wrong terms here.

I mean it is unexpected that when I make a line plot I can refer to locations on x-axis by their value (i.e. location 2.5 is between 2 and 3), but when I plot a bar plot I cannot (i.e. location 2.5 is between the third and fourth bars regardless of their x-value)

In general, barplots are categorical along the x-axis. Think about if your labels were ['a', 'b', 'c'], instead of [0, 1, 2]. We wouldn't expect ax.axvline('b', ...) to work.

I don't recall if matplotlib has anyway of doing this mapping in general. I would recommend something like

In [55]: loc = koe1.index.get_indexer([2, 3]).mean()

In [56]: ax.axvline(loc)

.get_indexer goes from index labels [2, 3] to positions ([1, 2] in this case).

I mean it is unexpected that when I make a line plot I can refer to locations on x-axis by their value

Just to be clear, this works because line plots are numeric, while barplots are categorical (agreed that it's somewhat intuitive).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

andreas-thomik picture andreas-thomik  路  3Comments

jaradc picture jaradc  路  3Comments

BDannowitz picture BDannowitz  路  3Comments

scls19fr picture scls19fr  路  3Comments

MatzeB picture MatzeB  路  3Comments