How to add text/label to a bar plot, when using pandas chaining ? Below is how I'm plotting without the label.
(
df
.groupby(['col1','col2'], dropna=False)
[['col1', 'col2']]
.size()
.unstack()
.plot(kind='bar', figsize = (8,8))
)
The unstacked data frame (right before .plot in the above code) has data as below.
col2 1.0 2.0 3.0 4.0 NaN
col1
1.0 514 1922 7827 18877 1966
2.0 NaN NaN NaN NaN 2018
NaN 21 20 59 99 5570
The plot is as below:
I would like to have the numbers displayed on top of the bars. Please advice. Thank you.
You have to get the output of your chaining (return an Axes instance):
ax = (df.groupby(['col1', 'col2'], dropna=False)[['col1', 'col2']]
.size().unstack()
.plot(kind='bar', figsize=(8, 8)))
for bars in ax.containers:
ax.bar_label(bars)
Output:
Update
I'm using 3.3.2 and cannot upgrade due to system restrictions
for rect in ax.patches:
height = rect.get_height()
ax.annotate(r'{:d}'.format(int(height)),
xy=(rect.get_x() + rect.get_width() / 2, height),
xytext=(0, 3),
textcoords="offset points",
ha='center', va='bottom')
Related
I have this df:
Month MEAN
0 JAN 1.0
1 FEB 2.0
2 MAR 5.0
3 APR 3.0
4 MAY 4.0
5 JUN 2.0
6 JUL 1.0
7 AUG 1.0
8 SEP 0.0
9 OCT 0.0
10 NOV 2.0
11 DEC 3.0
I want to annotate the values of my plot in a lineplot graphic, so i tried this code:
fig = plt.figure('Graphic', figsize=(20,15), dpi=300)
ax1 = fig.add_axes([0.15, 0.20, 0.70, 0.60])
df.plot(kind='line', marker='o',style=['--'],linewidth=7,color='black', ms=15,ax=ax1)
for x,y in zip(df['Month'],df['MEAN']):
label = "{:.2f}".format(y)
plt.annotate(label, # this is the text
(x,y),
textcoords="offset points",
xytext=(0,10),
ha='center')
But i get this error:
ConversionError: Failed to convert value(s) to axis units: 'JAN'
How can i solve this?
pd: Maybe i should change df['Month'] values to numerical but i need to plot the string values in the graphic.
Thanks in advance.
This should work:
fig = plt.figure('Graphic', figsize=(20,15), dpi=300)
ax1 = fig.add_axes([0.15, 0.20, 0.70, 0.60])
df.plot(kind='line', marker='o',style=['--'],linewidth=7,color='black', ms=15,ax=ax1)
plt.xticks(range(0,len(df['Month'])), df['Month'])
plt.show()
Let me know if you have any questions.
As you are aware, the x-axis value must be a number, not a string, so the graph can be created by using the data frame index and then setting the string ticks.
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure('Graphic', figsize=(10,7.5), dpi=72)
ax1 = fig.add_axes([0.15, 0.20, 0.70, 0.60])
df.plot(kind='line', marker='o', style=['--'], linewidth=7, color='black', ms=15, ax=ax1)
for x,y in zip(df.index, df['MEAN']):
label = "{:.2f}".format(y)
plt.annotate(label, # this is the text
(x,y),
textcoords="offset points",
xytext=(0,10),
ha='center')
ax1.set_xticks(np.arange(0,12,1))
ax1.set_xticklabels(df['Month'].unique())
plt.show()
I have this dataframe called cases_deaths:
week daily_case_totals daily_death_totals
0 1 2.0 0.0
1 2 12.0 0.0
2 3 12.0 0.0
3 4 2.0 0.0
4 5 573.0 6.0
5 6 3134.0 12.0
6 7 3398.0 32.0
7 8 992.0 25.0
.
.
.
And this code to generate to Seaborn charts:
fig, axes = plt.subplots(2, 1, figsize=(11, 10))
for name, ax in zip(['daily_case_totals', 'daily_death_totals'], axes):
sns.barplot(data=cases_deaths, x='week', y=name, ax=ax, color = 'red')
And the chart looks like this:
But I want the top one to be blue and bottom to be red. Not sure how to do that, I've tried passing in a list of colors to the color parameter in the for loop but that yielded an error.
Just add one more iterable to zip for the colors:
import seaborn as sns
fig, axes = plt.subplots(2, 1, figsize=(11, 10))
for name, color, ax in zip(('daily_case_totals', 'daily_death_totals'),
('blue', 'red'),
axes):
sns.barplot(data=cases_deaths, x='week', y=name, ax=ax, color=color)
I need to plot a barchat and to apply a color according to the "Attribute" column of my dataframe
x axis = Shares
y axis = Price
fig, ax = plt.subplots()
ax.barh(df['Share'],df['Price'], align='center')
ax.set_xlabel('Shares')
ax.set_ylabel('Price')
ax.set_title('Bar Chart & Colors')
plt.show()
Thanks for your help !
There are two easy ways to plot the bars with separate colors for 'Attribute'
Transform the dataframe with .pivot and then plot with pandas.DataFrame.plot and specify kind='barh' for a horizontal bar plot
The index will be the x-axis if using kind='bar', and will be the y-axis if using kind='barh'
The columns of the transformed dataframe will each be plotted with a separate color.
pandas uses matplotlib as the default plotting backend.
Use seaborn.barplot with hue='Attribute' and orient='h'. This option works with the dataframe in a long format, as shown in the OP.
seaborn is a high-level API for matplotlib
Tested with pandas 1.3.0, seaborn 0.11.1, and matplotlib 3.4.2
Imports and DataFrame
import pandas as pd
import seaborn as sns
# test dataframe
data = {'Price': [110, 105, 119, 102, 111, 117, 110, 110], 'Share': [110, -50, 22, 79, 29, -2, 130, 140], 'Attribute': ['A', 'B', 'C', 'D', 'A', 'B', 'B', 'C']}
df = pd.DataFrame(data)
Price Share Attribute
0 110 110 A
1 105 -50 B
2 119 22 C
3 102 79 D
4 111 29 A
5 117 -2 B
6 110 130 B
7 110 140 C
pandas.DataFrame.plot
# transform the dataframe with .pivot
dfp = df.pivot(index='Price', columns='Attribute', values='Share')
Attribute A B C D
Price
102 NaN NaN NaN 79.0
105 NaN -50.0 NaN NaN
110 110.0 130.0 140.0 NaN
111 29.0 NaN NaN NaN
117 NaN -2.0 NaN NaN
119 NaN NaN 22.0 NaN
# plot
ax = dfp.plot(kind='barh', title='Bar Chart of Colors', figsize=(6, 4))
ax.set(xlabel='Shares')
ax.legend(title='Attribute', bbox_to_anchor=(1, 1), loc='upper left')
ax.grid(axis='x')
with stacked=True
ax = dfp.plot(kind='barh', stacked=True, title='Bar Chart of Colors', figsize=(6, 4))
seaborn.barplot
Note the order of the y-axis values are reversed compared to the previous plot
ax = sns.barplot(data=df, x='Share', y='Price', hue='Attribute', orient='h')
ax.set(xlabel='Shares', title='Bar Chart of Colors')
ax.legend(title='Attribute', bbox_to_anchor=(1, 1), loc='upper left')
ax.grid(axis='x')
Hello World,
Below is an example of my df
df
Date Name x1 x2 x3 x4
01/01/16 aa 10 15 20 11
01/01/16 bb 10 10 50 14
02/01/16 aa 12 30 17 25
02/01/16 bb 17 10 14 25
...
Question:
How can I plot on:
x-axis the date
y-axis x1,x2,x3, x4
hue Name
What I have done so far, gives me the following output
g= df.plot(x="date", y=['x1', 'x2', 'x3', 'x4'], figsize=(30,10), kind='bar')
The expected output will be the same as above but with the Name as title.
I thought of hue argument like in seaborn but not working with pandas.plot
Thanks for everyone helping!
with dataframe melt as per J.K., some chart options:
import seaborn as sns
sns.barplot(x="Date", y='values', hue='Name', data=df, ci=None)
sns.catplot(data=df, x='Date', y='values', hue='Name', kind="bar", ci=None)
the ci removes the confidence interval draw if you do not need it
Try this on your dataframe:
df = df.melt(id_vars=['Date', 'Name'], value_name='values',
var_name='variables')
sns.catplot(data=df, x='Date', y='values', hue='variables', col='Name',
kind="bar")
I have a dataframe,df with 29 rows by 24 columns dimension
Index 0.0 5.0 34.0 ... 22.0
2017-08-03 00:00:00 10 0 10 0
2017-08-04 00:00:00 20 60 1470 20
2017-08-05 00:00:00 0 58 0 24
2017-08-06 00:00:00 0 0 480 24
2017-09-07 00:00:00 0 0 0 25
: : : : :
: : : : :
2017-09-30 00:00:00
I intend to label bins for each subplot representing a column in the histogram chart.I have been able to draw the histogram in each subplot for each column using this code
fig = plt.figure(figsize = (15,20))
ax = fig.gca()
#Initialize the figure
plt.style.use('seaborn-darkgrid')
df.hist(ax = ax)
However, the labels of the bins of each subplot are far apart and bin labels are not explicitly specified by ranges on the x-axis which is difficult to interpret. I have looked at
Aligning bins to xticks in plt.hist but it doesnt explicitly solve for labelling bins when subplots are concerned. Any help will be great...
I have also tried this but i get ValueError: too many values to unpack (expected 2)
x=[0,40,80,120,160,200,240,280,320]
fig = plt.figure(figsize = (15,20))
ax = fig.gca()
# Initialize the figure
plt.style.use('seaborn-darkgrid')
n,bins= plt.hist(df,bins= x)
#labels & axes
plt.locator_params(nbins=8, axis='x')
plt.ticklabel_format(style='sci', axis='x', scilimits=(0,0))
plt.title('Daily occurrence',fontsize=16)
plt.xlabel('Number of occurrence',fontsize=12)
plt.ylabel('Frequency',fontsize=12)
plt.xticks(x)
plt.xlim(0,320)