8

I am plotting a bar graph by reading data from a CSV using pandas in Python. I read a CSV into a DataFrame and plot them using matplotlib.

Here is how my CSV looks like:

SegmentName    Sample1   Sample2   Sample3

Loop1          100       100       100

Loop2          100       100       100

res = DataFrame(pd.read_csv("results.csv", index_col="SegmentName"))

I plot and set the legend to be outside.

plt.figure()
ax = res.plot(kind='bar')
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))

plt.savefig("results.jpg")

However, the x-axis ticklabels are orientated vertically and hence I can't read the text. Also my legend outside is cut off.

Can I change the orientation of the ticklabels to be horizontal, and then adjust the entire figure so that the legend is visible?

enter image description here

sodd
  • 12,482
  • 3
  • 54
  • 62
user2450971
  • 131
  • 1
  • 1
  • 5
  • Ofcourse we need, import numpy as np import pandas as pd from pandas import * import matplotlib.pyplot as plt – user2450971 Aug 07 '13 at 08:12
  • Include a link to your image, so we can update your question to include the image. – sodd Aug 07 '13 at 09:09
  • Here is the screenshot. http://imageshack.us/photo/my-images/14/srzn.jpg/ – user2450971 Aug 07 '13 at 19:43
  • It seems you are trying to rotate the _ticklabels_ on the x-axis rather than the _label_, which is another object entirely. You should update your question to clarify. – sodd Aug 07 '13 at 20:05
  • Plot also has an argument. For example df.plot(kind='bar', rot=0) for horizontal orientation – SMeznaric Feb 11 '16 at 13:04

3 Answers3

11

Try using the 'rotation' keyword when you set the label. E.g.:

plt.xlabel('hi',rotation=90)

Or if you need to rotate the tick labels, try:

plt.xticks(rotation=90)

As for the positioning of the legend etc., it is probably worth taking a look at the tight layout guide

Dman2
  • 700
  • 4
  • 10
  • This will rotate the ticklabels on the x-axis, not the axis label, so I believe this does not achieve what the OP wants. – sodd Aug 07 '13 at 09:14
  • Ahh I see. Either way, the 'rotation' keyword is the main point - it can be passed into a label function. Updating answer. – Dman2 Aug 07 '13 at 09:37
  • Here is the screenshot of my plot. http://imageshack.us/photo/my-images/14/srzn.jpg/ – user2450971 Aug 07 '13 at 19:24
  • From the image provided by OP right now, it seems your first solution was correct after all; he is trying to rotate the _ticklabels_, not the label as he has written in his question. – sodd Aug 07 '13 at 20:04
  • Sorry, I used the above solution, but my plot still looks the same. I loop1, loop2 to be Horizontal orientation instead of vertical as shown in my figure. Also, how do I change the plot size so that I can see my legend. They are cut off. – user2450971 Aug 07 '13 at 20:35
  • 1
    I've updated my answer which should help you out and point you in the right direction. – Dman2 Aug 08 '13 at 09:11
5

You should use the matplotlib API and call ax.set_xticklabels(res.index, rotation=0) like so:

index = Index(['loop1', 'loop2'], name='segment_name')
data = [[100] * 3, [100] * 3]
columns = ['sample1', 'sample2', 'sample3']
df = DataFrame(data, index=index, columns=columns)

fig, ax = subplots()
df.plot(ax=ax, kind='bar', legend=False)
ax.set_xticklabels(df.index, rotation=0)
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
fig.savefig('results.png', bbox_inches='tight')

to get the resulting plot:

enter image description here

Alternatively you can call fig.autofmt_xdate() for a nice tilted effect, which you can of course tinker with with the above (and more general) ax.set_xticklabels():

fig, ax = subplots()
df.plot(ax=ax, kind='bar', legend=False)
fig.autofmt_xdate()
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
fig.savefig('results-tilted.png', bbox_inches='tight')

enter image description here

Phillip Cloud
  • 24,919
  • 11
  • 68
  • 88
  • when I try and use ax = dataframe.plot() AND "ax.set_xticklabels(df.month_date, rotation=90)" I get the error 'numpy.ndarray' object has no attribute 'set_xticklabels'. I just want my x axis label to rotate so the text reads the date, vertical from top to bottom! – yoshiserry Dec 01 '14 at 23:34
5

For the rotation of the labels, you can simply tell pandas to rotate it for you by giving the number of degrees to the rot argument. The legends being cut off is answered elsewhere as well, like here:

df = pd.DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6])],
                              orient='index', columns=['one', 'two', 'three'])
ax = df.plot(kind='bar', rot=90)
lgd = ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
fig.savefig("results.jpg", bbox_extra_artists=(lgd,), bbox_inches='tight')
Community
  • 1
  • 1
Mahdi
  • 1,778
  • 1
  • 21
  • 35