2

I have the following data frame:

    land_cover  canopy_cat  count  tc_density_cor
0           20           1     56       35.760967
1           20           2     28       35.760967
2           20           3     11       35.760967
3           20           4      9       35.760967
4           20           5      4       35.760967
5           20           6      3       35.760967
6           20           7      3       35.760967
7           20           8      1       35.760967
8           20           9      4       35.760967
9           20          10      6       35.760967
10          20          11      2       35.760967
11          30           1    194       17.408260
12          30           2     86       17.408260
13          30           3     55       17.408260
14          30           4     36       17.408260
15          30           5     21       17.408260
16          30           6     15       17.408260
17          30           7      9       17.408260
18          30           8      6       17.408260
19          30           9     19       17.408260
20          30          10     14       17.408260
21          30          11      9       17.408260
22          40           1    106       17.458283
23          40           2     45       17.458283
24          40           3     19       17.458283
25          40           4     14       17.458283
26          40           5      9       17.458283
27          40           6      8       17.458283
28          40           7      5       17.458283
29          40           8      5       17.458283
30          40           9      8       17.458283
31          40          10     12       17.458283
32          40          11      3       17.458283


and I want to plot my data as a stacked bar plot:
x-axis = land_cover
y-axis = count per canopy_cat

I think that the pivot function is what I am looking for. However before I want to normalize the "count" column for each land_cover relative to "tc_density_cor".
for example, the sum of "counts" for land_cover=20 = 127.
127/35.76 = 56/x --> new value would be: 15.76

How can I do that?? :)

1
  • 1
    I put in text instead.. Commented Aug 8, 2018 at 13:16

2 Answers 2

2

I think you need:

df['Count Per Canopy Cat'] = (df['count'] * df['tc_density_cor'] / 
                              df.groupby('land_cover')['count'].transform(sum))

df.pivot('land_cover',
         'canopy_cat',
         'Count Per Canopy Cat')\
  .plot.bar(stacked=True, figsize=(15,8))

Chart:

enter image description here

Sign up to request clarification or add additional context in comments.

3 Comments

fantastic - both works well! thanks. an additional question: can I adjust the bar width depending on a column, let's call it "class_size" with one value for each land_cover? Thanks!
Not using this method, the width parameter expects a float from 0 to 1.
yes, the value would be somewhere between 0 and 1. let's say 0.2 for land_cover 20 and 0.8 for land_cover 30...
2

IIUC

d = df.set_index(
    ['land_cover', 'canopy_cat']
).pipe(
    lambda d: d['count'].div(d['count'].sum(level=0), axis=0, level=0) * d['tc_density_cor']
).unstack()

d.iloc[:, :5]

canopy_cat          1         2         3         4         5
land_cover                                                   
20          15.768615  7.884308  3.097407  2.534242  1.126330
30           7.278454  3.226531  2.063479  1.350641  0.787874
40           7.908453  3.357362  1.417553  1.044513  0.671472

d.plot.bar(stacked=True)

enter image description here


Same answer refactored

def normalize(d):
    sums = d['count'].sum(level='land_cover')
    return d['count'].div(sums, axis=0, level='land_cover') * d['tc_density_cor']

d = df.set_index(['land_cover', 'canopy_cat']).pipe(normalize).unstack()

d.plot.bar(stacked=True)

1 Comment

that works very well. thanks a lot! can I also adjust the bar width depending on a column, let's call it "class_size" with one value for each land_cover (value between 0 and 1)?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.