0

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 [![stacked_barplot][2]][2]

ZVY545
  • 384
  • 1
  • 13

1 Answers1

0

Heres I managed to get a solution of this problem:

stacked-bar-plotimport numpy as np import matplotlib.pyplot as plt import pandas as pd

df_final=pd.read_csv(r"D:/D50 python/sediment/final df/table.dat",delimiter='\t' )

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']]

dfp=dfp.apply(lambda x: [0 if y <= 0 else y for y in x])
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')




dfp_r=dfp.set_index('node').apply(lambda x: [0 if y <= 0.02 else 1 for y in x])
df50_r=df50*dfp_r.values
df50_r1=df50_r.round(2).apply(lambda x: ['' if y <= 0.02 else y for y in x])
a=df50_r1.T.values.tolist()


for c,lbl in zip(ax.containers,a):
    
    ax.bar_label(c, labels=lbl,fmt='%0.2f', label_type='center')


plt.ylim([0,13])


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)
ZVY545
  • 384
  • 1
  • 13