Reputation: 4023
I have this df
:
df = pd.DataFrame({'A': [1, 2, 3], 'B': [2, 3, 5], 'C': ['name 1', 'name 2', 'name 3']})
A B C
0 1 2 name 1
1 2 3 name 2
2 3 5 name 3
What is it the correct way to plot column A
and use column C
as xticks?
These do not work:
df['A'].plot(xticks='C')
df['A'].plot(xticks=df['C'])
This changes the xticks but not the labels:
df['A'].plot(xticks=[1,2,3])
Should I really convert to sequence? I have also some modification of the question. I got next Error message:
ValueError: could not convert string to float: name 3
In short, I have a column of strings and want to use it as xticks for my plot.
PS: It doesn't look like there's a direct pandas plot function. I found a solution here.
Upvotes: 47
Views: 173246
Reputation: 23131
When you call plot()
, you can pass column names as axis values to use its values as tick labels. So for the question in the OP, the following works.
df.plot(y='A', x='C', legend=False);
or you can set column C as index and just call plot
on column A:
df.set_index('C')['A'].plot();
You can also plot multiple column values in one plot by passing a list of column names:
df.plot(y=['A', 'B'], x='C');
Upvotes: 0
Reputation: 41327
Use ax.set_xticks
with the new labels
param to set ticks and labels simultaneously:
ax = df.plot(y='A')
ax.set_xticks(ticks=df.index, labels=df.C)
# ^^^^^^
Or, since df.plot
returns an Axes
object, we can chain it:
df.plot(y='A').set_xticks(df.index, df.C)
Note that plt.xticks
always had a labels
param, so this change just unifies the Axes
and pyplot
APIs.
Upvotes: 6
Reputation: 3411
The link you provided is a good resource, but shows the whole thing being done in matplotlib.pyplot
and uses .subplots()
to get to the axes. While I've done this before, I keep searching for ways to just use the built-into-pandas .plot()
function as much as possible. To me it can simplify the code and makes it easier to leverage DataFrame goodness.
There do seem to be a number of things that aren't easy to do fully inside the parameters of df.plot()
by itself, though. Luckily it returns an matplotlib.AxesSubplot
, which opens up a much larger range of possibilities.
I copied your data above into a DataFrame:
df = pd.read_clipboard(quotechar="'")
It looks sort-of like:
A B C
0 1 2 'name 1'
1 2 3 'name 2'
2 3 5 'name 3'
But, of course, much better in non table-crippled html. (Maybe SO will fix this one day).
Then all I had to do was:
ax = df.A.plot(xticks=df.index, rot=90)
ax.set_xticklabels(df.C)
If you are using IPython/Jupyter and %matplotlib inline
then both of those need to be in the same cell. I had forgotten that at first and spent quite a bit of time trying to figure what was going wrong.
You can do it all using the ax
variable:
ax = df.A.plot()
ax.set_xticks(df.index)
ax.set_xticklabels(df.C, rotation=90)
but, as I mentioned, I haven't found a way to the xticklabels
inside the df.plot()
function parameters, which would make it possible to do this all in a single line.
The extra step to rotate the xtick labels may be extraneous in this example, but came in handy in the one I was working on when looking for this answer.
And, of course, you can plot both A and B columns together even easier:
ax = df.plot()
ax.set_xticks(df.index)
ax.set_xticklabels(df.C, rotation=90)
Upvotes: 102