28

Say I have data in following format:

Region   Men   Women
City1    10   5
City2    50   89

When I load it in Dataframe and plot graph, it shows index as X-axis labels instead of Region name. How do I get names on X-axis?

So far I tried:

import pandas as pd
import matplotlib.pyplot as plt    
plt.style.use('ggplot')
ax = df[['Men','Women']].plot(kind='bar', title ="Population",figsize=(15,10),legend=True, fontsize=12)
ax.set_xlabel("Areas",fontsize=12)
ax.set_ylabel("Population",fontsize=12)
plt.show()

Currently it shows x ticks as 0,1,2..

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Volatil3
  • 14,253
  • 38
  • 134
  • 263
  • 2
    [`plt.xticks()`](http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.xticks) [(example)](http://matplotlib.org/examples/ticks_and_spines/ticklabels_demo_rotation.html) or [`ax.set_xticklabels()`](http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.set_xticklabels) might be worth looking into (docs linked for each). There's also the `xticks` parameter you can specify to [`DataFrame.plot()`](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.plot.html) – jedwards Jul 31 '16 at 12:01
  • @jedwards `set.xticklabels()` worked but it's weird showing string vertically instead of horizontally. – Volatil3 Jul 31 '16 at 12:04
  • Like, the labels are rotated? In other words, to read them "properly" you'd have to turn your head? Or the label is very narrow and each letter or two is on a new line. – jedwards Jul 31 '16 at 12:04
  • like showing `NYC` in stack, `N` on top and `C` at bottom – Volatil3 Jul 31 '16 at 12:05
  • @jedwards Check this: http://imgur.com/a/65WCB – Volatil3 Jul 31 '16 at 12:07
  • Is that what you want, or what you have? If that's what you have, do you want them "not rotated"? – jedwards Jul 31 '16 at 12:08
  • @jedwards I want the region name shows horizontally. I already sent image about what's going wrong. – Volatil3 Jul 31 '16 at 12:09
  • 2
    That's odd, because for me it defaults to horizontal text. Does specifying `rotation=0` help at all? As in, `set_xticklabels(, rotation=0)`? – jedwards Jul 31 '16 at 12:11
  • 1
    @jedwards Perfect! Can you make it as an answer? – Volatil3 Jul 31 '16 at 12:12
  • Done -- glad you got it sorted out :) – jedwards Jul 31 '16 at 12:17

3 Answers3

19

plot.bar() method inherits its arguments from plot(), which has rot argument:

from the docs:

rot : int, default None

Rotation for ticks (xticks for vertical, yticks for horizontal plots)

it also uses per default index as ticks for x axis:

use_index : boolean, default True

Use index as ticks for x axis

In [34]: df.plot.bar(x='Region', rot=0, title='Population', figsize=(15,10), fontsize=12)
Out[34]: <matplotlib.axes._subplots.AxesSubplot at 0xd09ff28>

alternatively you can set index explicitly - it might be useful for multi-level indexes (axes):

df.set_index('Region').plot.bar(rot=0, title='Population', figsize=(15,10), fontsize=12)

enter image description here

MaxU - stand with Ukraine
  • 205,989
  • 36
  • 386
  • 419
15

Since you're using pandas, it looks like you can pass the tick labels right to the DataFrame's plot() method. (docs). (e.g. df.plot(..., xticks=<your labels>))

Additionally, since pandas uses matplotlib, you can control the labels that way.

For example with plt.xticks() (example) or ax.set_xticklabels()

Regarding the rotation, the last two methods allow you to pass a rotation argument along with the labels. So something like:

ax.set_xticklabels(<your labels>, rotation=0)

should force them to lay horizontally.

jedwards
  • 29,432
  • 3
  • 65
  • 92
2

I had a lot of trouble finding an answer I really liked for this, the below function achieves it quite well, and is very adaptable,

def plot_vals_above_titles(data_frame, columns):
    import random
    y_vals = {}

    fig = plt.figure()
    plt.grid(True)

    for index, row in data_frame.iterrows():
        x_coord = 0

        for col in columns:
            # add some jitter to move points off vertical line
            jitter = random.uniform(-0.1,.1)
            x_coord += jitter

            plt.scatter(
                x = x_coord,
                y = row[col]
                )

            x_coord -= jitter
            x_coord+=1

    # rename the xticks with column names
    x_vals = range(0, len(columns))
    plt.xticks(x_vals, columns)

Below is an example of my result, though I set a new color for each value in a separate column in the dataframe

My columns were titled ['A','B','C','D','E']

nbenz
  • 41
  • 5