how to plot a dataframe with two different axes in pandas matplotlib - pandas

So my data frame is like this:
6month final-formula numPatients6month
160243.0 1 0.401193 417
172110.0 2 0.458548 323
157638.0 3 0.369403 268
180306.0 4 0.338761 238
175324.0 5 0.247011 237
170709.0 6 0.328555 218
195762.0 7 0.232895 190
172571.0 8 0.319588 194
172055.0 9 0.415517 145
174609.0 10 0.344697 132
174089.0 11 0.402965 106
196130.0 12 0.375000 80
and I am plotting 6month, final-formula column
dffinal.plot(kind='bar',x='6month', y='final-formula')
import matplotlib.pyplot as plt
plt.show()
till now its ok, it shows 6month in the x axis and final-formula in the y-axis.
what I want is that to show the numPatients6month in the same plot, but in another y axis.
according to the below diagram. I want to show numPatients6month in the position 1, or simply show that number on above each bar.
I tried to conduct that by twinx, but it seems it is for the case we have two plot and we want to plot it in the same figure.
fig = plt.figure()
ax = fig.add_subplot(111)
ax2 = ax.twinx()
ax.set_ylabel('numPatients6month')
I appreciate your help :)

This is the solution that resolved it.I share here may help someone :)
ax=dffinal.plot(kind='bar',x='6month', y='final-formula')
import matplotlib.pyplot as plt
ax2 = ax.twinx()
ax2.spines['right'].set_position(('axes', 1.0))
dffinal.plot(ax=ax2,x='6month', y='numPatients6month')
plt.show()

Store the AxesSubplot in a variable called ax
ax = dffinal.plot(kind='bar',x='6month', y='final-formula')
and then
ax.tick_params(labeltop=False, labelright=True)
This will, bring the labels to the right as well.
Is this enough, or would you like to also know how to add values to the top of the bars? Because your question indicated, one of the two would satisfy.

Related

How to add a legend to a figure

I would like to add a legend into my figure. This is the code i used to print the plot:
fig1, ax1 = plt.subplots()
ax1.legend("Test Legend")
ax1.plot(singleColumn)
This is the plot i get:
fig1 plot
If i use this code:
print(singleColumn.plot(legend=True))
Perfect Plot
I will get a perfect plot with a legend, but if i plot other figures, all plots are mixed up, so i would prefer the fig method.
How i add the Name of the Data into the fig1 plot ?
Best regards
Kai
edit:
The sinmgleColumn looks like that, i displayed the head:
[5 rows x 13 columns]
MESSDATUM
2011-01-10 2.40
2011-02-02 2.17
2011-03-03 2.32
2011-04-06 1.67
2011-05-04 2.56
Name: 2433876, dtype: float64

How to add an extra number on top of the each bar on barchart

According to the explanation why this question is different from this link
this link get the height from the diagram as far as I understood, but in my case I do not have this column numpatients6month in the diagram at all, I just have that on the data frame.
So I have a bar chart. It contains two bar for each x-axis in which each bar read from different data frame.
this is the code I am plotting the bar chart.
import seaborn as sns
import matplotlib.pyplot as plt
plt.rcParams['axes.prop_cycle'] = ("cycler('color', 'rg')")
dffinal['CI-noCI']='Cognitive Impairement'
nocidffinal['CI-noCI']='Non Cognitive Impairement'
res=pd.concat([dffinal,nocidffinal])
sns.barplot(x='6month',y='final-formula',data=res,hue='CI-noCI').set_title(fs)
plt.xticks(fontsize=8, rotation=45)
plt.show()
as you see there is two data frame. I plot dffinal with color green and nocidffinal with color red.
This is the result of plot:
Some more explanation: dffinal is based on (6month, final-formula) nocidffinal is also based on(6month,final-formula).
this is my nocidffinal data frame:
6month final-formula numPatients6month
137797.0 1 0.035934 974
267492.0 2 0.021705 645
269542.0 3 0.022107 769
271950.0 4 0.020000 650
276638.0 5 0.015588 834
187719.0 6 0.019461 668
218512.0 7 0.011407 789
199830.0 8 0.008863 677
269469.0 9 0.003807 788
293390.0 10 0.009669 724
254783.0 11 0.012195 738
300974.0 12 0.009695 722
and dffinal:
6month final-formula numPatients6month
166047.0 1 0.077941 680
82972.0 2 0.057208 437
107227.0 3 0.057348 558
111330.0 4 0.048387 434
95591.0 5 0.033708 534
95809.0 6 0.036117 443
98662.0 7 0.035524 563
192668.0 8 0.029979 467
89460.0 9 0.009709 515
192585.0 10 0.021654 508
184325.0 11 0.017274 521
85068.0 12 0.010438 479
As you see there is column numPatients6month in this dataframeS which I would like to show on top of each bar.
I do NOT want to change the barchart and group it based on this column, rather I want to just show this number as extra information to the user on top of each bar.
thanks for your time :)
If you get your numPatients6month columns in one iterable and in order they appear in chart then using the other stackoverflow answer (also in the docs here) you can place the text on top correctly.
I used code below (adapted from this SO answer). It combines multiple columns one row after another (i.e. will get all your numPatients6month columns in the chart order)
vals = pd.concat([nocidffinal.numPatients6month, dffinal.numPatients6month], axis=1)
vals = vals.stack().reset_index(level=[0,1], drop=True)
This is my full code
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['axes.prop_cycle'] = ("cycler('color', 'rg')")
dffinal['CI-noCI']='Cognitive Impairement'
nocidffinal['CI-noCI']='Non Cognitive Impairement'
res=pd.concat([dffinal,nocidffinal])
# Copied to clipboard from SO question above
# Comment out if you already have your dataframes
nocidffinal = pd.read_clipboard().reset_index()
dffinal = pd.read_clipboard().reset_index()
# This will merge columns in order of the chart
vals = pd.concat([nocidffinal.numPatients6month, dffinal.numPatients6month], axis=1)
vals = vals.stack().reset_index(level=[0,1], drop=True)
# Plot the chart
ax = sns.barplot(x='6month', y='final-formula', data=res, hue='CI-noCI')
_ = plt.xticks(fontsize=8, rotation=45)
# Add the values on top of each correct bar
for idx, p in enumerate(ax.patches):
height = p.get_height()
ax.text(p.get_x()+p.get_width()/2.,
height + height*.01,
vals[idx],
ha="center")

Showing one label on pie chart pandas

Is there a way of showing just one set of label? At the moment it is looking very messy and I would like to have one set of label please. I did label=None and it turned off all the labels.
Thanks
I think you need a bit change How to make MxN piechart plots with one legend and removed y-axis titles in Matplotlib:
df = pd.DataFrame({'beer':[1,2,3],
'spirit':[4,5,6],
'wine':[7,8,9]}, index=['Africa','Asia','Europe'])
print (df)
beer spirit wine
Africa 1 4 7
Asia 2 5 8
Europe 3 6 9
fig, axes = plt.subplots(1,3, figsize=(10,3))
for ax, idx in zip(axes, df.index):
ax.pie(df.loc[idx], labels=df.columns, autopct='%.2f')
ax.set(ylabel='', title=idx, aspect='equal')
axes[0].legend(bbox_to_anchor=(0, 0.5))
plt.show()

Line graphs in matplotlib

I am plotting the below data frame using google charts.
Hour S1 S2 S3
1 174 0 811
2 166 0 221
3 213 1 1061
But with google charts, I am not able to save it to a file. Just wondering whether I can plot the dataframe in matplotlib line charts.
Any help would be appreciated.
pandas has charting method, just do:
df.plot()
where df is your pandas dataframe
matplotlib 1.5 and above supports a data wkarg
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot('S1', 'S2', data=df)
or just directly pass in the columns as input
ax.plot(df['S1'])

Legend and title to line charts using matplotlib

I am plotting the below data frame using google charts.
Group G1 G2
Hour
6 19 1
8 1 2
I have plotted the above dataframe in line chart. But i am not able to add legend and title to the line chart. And also, I am trying to increase the size of the line charts as it appears to be very small. Not sure whether do we have these options in matplotlib. Any help would be appreciated.
import matplotlib.pyplot as plt
plt.plot(dft2)
plt.xlabel('Hour')
plt.ylabel('Count')
plt.show()
dfg2.plot(legend=True, figsize=(8,8))
plt.legend(ncol=3, bbox_to_anchor=[1.35, 1], handlelength=2, handletextpad=1, columnspacing=1, title='Legend')
plt.title('Title here!', color='black', fontsize=17)
plt.xlabel('Hour', fontsize=15)
plt.ylabel('Count', fontsize=15)
plt.show()