I have two dataframes,dfp and df50.I will use dfp to plot stacked barplot of layer thickness (t_L) for different nodes. Following is dfp:
dfp
Out[366]:
node t_L1 t_L2 t_L3 t_L4 t_L5
75 1000 10.000000 0.997805 0.000000 0.001757 0.001277
76 1200 8.695543 0.495119 0.704963 0.194004 0.011915
77 1800 10.000000 0.997652 0.331684 1.067279 0.002962
78 2000 10.000000 0.984361 0.000000 0.009542 0.003020
79 3000 10.000000 0.321650 0.000000 0.000000 0.004485
Another dataframe is df50.
df50
Out[367]:
d50_L1 d50_L2 d50_L3 d50_L4 d50_L5
node
1000 0.203694 0.036318 0.010000 0.036137 0.010000
1200 0.269794 0.707631 0.880470 0.974645 1.027640
1800 0.269794 0.269794 0.277525 0.432579 0.705985
2000 0.203694 0.036318 0.060096 0.049557 0.060096
3000 0.269794 0.269794 0.279907 0.279907 0.279894
I want to show these d50(50% finer) values in the patches of the stacked barplots. Now, there are cases when a few of the barplot sections are zero because of zero thickness (t_L=0.000). So, I will have to write a forloop for the bar containers so that the label(d50 value for that patch) becomes blank of '' when v.get_height()<=0 . I could come up with the following code:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# from plotnine import *
# from plotnine.data import mtcars
df_final=pd.read_csv(r"D:/D50 python/sediment/final df/table.dat",delimiter='\t' )
### single TS
plt.figure(figsize=(8, 6))
plt.rcParams.update({'font.size': 12})
df=df_final[df_final['TS'].isin([200102419])]
dfp = df[['node','t_L1','t_L2','t_L3','t_L4','t_L5']]
ax=dfp.plot(x='node',kind='bar',stacked=True )
df50 = df[['node','d50_L1','d50_L2','d50_L3','d50_L4','d50_L5']].set_index('node')
a=df50.round(2).T.values.tolist() # labels for containers needed to be transposed
for c,lbl in zip(ax.containers,a):
# customize the label to account for cases when there might not be a bar section
labels = [lbl if v.get_height() > 0 else '' for v in c]
# labels = [lbl if v.get_height() > 0.0 else '' for lbl in a]
# labels = [lbl if lbl > 0.0 else '' for v in c]
# ax.bar_label(c, labels=labels,fmt='%0.2f', label_type='center')
ax.bar_label(c, labels=lbl,fmt='%0.2f', label_type='center')
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))
plt.ylabel('Thickness', fontsize=10)
plt.xlabel('Node', fontsize=10)
plt.savefig(r"D:/D50 python/sediment/final df/stacked_barplot.png",bbox_inches='tight',dpi=300)
I got the following plot which shows misplaced d50 values for the zero thickness layers. Please let me know if there is a way to fix the forloop so that the d50 value is not showed for the zero thickness patches. Also please find the input file here: https://drive.google.com/file/d/1c-P71EQdyT9TCOare1wORHnfO8YsbGni/view?usp=sharing
[![stacked_barplot][2]][2]