0
votes

I want to create a grouped bar chart that shows the median and mean of each group. I'm also using an animation frame to show how each median and mean changes based on the ubi amount.

I want to group these bar charts so that it shows median and mean for each group and how it changes.

Here is my code but I'm stuck on how to group them.

import pandas as pd
import plotly.express as px

summary_med = pd.read_csv('https://github.com/ngpsu22/indigenous-peoples-day/raw/main/native_medians_means')

fig = px.bar(summary_med, x = 'race', y='med_resources_per_person',
         animation_frame='monthly_ubi', range_y=[0,25_000],
         labels={
                 "med_resources_per_person": "Median resources per person",
                 "race": "Race",
                 "monthly_ubi": "Monthly UBI",
                 "native": "Native",
                 "non_native": "Non-native"
             },
            title="Tax funded UBI and median resources per person", 
         color='race', 
         text='med_resources_per_person',
         height=900, width=800,
         color_discrete_map={'native': '#5886a5',
                             'non_native': '#5886a5'})

fig.update_traces(texttemplate='$%{text}')
fig.update_layout(showlegend=False, yaxis_tickprefix='$')
fig.show()
2
Do you mind to specify with respect to what column do you want to group by?rpanai
Sorry I want to group by "Native" and "Non-native". So the result should the median and mean for each of those groups. So the race column.user13747020

2 Answers

2
votes

I'm not sure if this is what you are asking for

import pandas as pd
import plotly.express as px

url = 'https://github.com/ngpsu22/indigenous-peoples-day/raw/main/native_medians_means'
df = pd.read_csv(url)

# wide to long
df = pd.melt(df,
        id_vars=["monthly_ubi", "race"],
        value_vars=['med_resources_per_person',
                    'mean_resources_per_person'],
        var_name="resource",
             
        value_name="y")


# Format text
diz_resource = {"med_resources_per_person": "Median",
                "mean_resources_per_person": "Mean"}
diz_race = {"native": "Native",
            "non_native": "Non-native"}

df["resource"] = df["resource"].map(diz_resource)
df["race"] =  df["race"].map(diz_race)

# Range max
range_max = df["y"].max() * 1.2

# Plot
fig = px.bar(df, 
       x='race',
       y="y",
       color="resource",
       barmode='group',
       animation_frame='monthly_ubi',
       text='y',
       height=900, width=800,
       labels={"race": "Race",
               "monthly_ubi": "Monthly UBI",
               "y": "Resource Per Person"
             },
       title="Tax funded UBI and median resources per person",
       range_y=[0, range_max]
    )
fig.update_traces(texttemplate='$ %{text}')
fig.update_layout(title_x=0.5,
#                   showlegend=False,
                  yaxis_tickprefix='$')
fig.show()

enter image description here

1
votes

Here is a solution without modifing the dataframe. Yet I didn't find a good method to display the variable name (median, mean) without legend so far. I also modified the color to show difference, but you can change the color to the same if you like.

the code would be :

import pandas as pd 
import plotly.express as px


summary_med = pd.read_csv('https://github.com/ngpsu22/indigenous-peoples-day/raw/main/native_medians_means')

fig = px.bar(summary_med, x="race", y=["med_resources_per_person","mean_resources_per_person"],
             # color='race', 
             animation_frame='monthly_ubi', 
             range_y=[0,50_000],
             barmode='group', # make it side by side 
             # height=400
              labels={
                 "med_resources_per_person": "Median",
                 "mean_resources_per_person":"Mean",
                 "race": "Race",
                 "monthly_ubi": "Monthly UBI",
                 "native": "Native",
                 "non_native": "Non-native"
             },
            title="Tax funded UBI and median resources per person", 

            height=900, width=800,
            color_discrete_map={'med_resources_per_person': '#5886a5','mean_resources_per_person': '#58a577'}

            ) 
fig.update_traces(texttemplate='%{y}') 
fig.update_layout(showlegend=True, yaxis_tickprefix='$') 
fig.show()

enter image description here