Home > Net >  How to show individual values from specific condition of dataframe for each bar using plotly python?
How to show individual values from specific condition of dataframe for each bar using plotly python?

Time:07-04

I have a several dataframes with user's order information like that:

A = {
    'user': ['a', 'b', 'c', 'd', 'e', 'f'],
    'country': ['UK', 'US', 'US', 'UK', 'UK', 'US'],
    'order': [1, 2, 2, 4, 4, 4]}

B = {
    'user': ['a', 'b', 'c', 'd', 'e', 'f'],
    'country': ['US', 'US', 'UK', 'FR', 'UK', 'US'],
    'order': [2, 2, 3, 3, 3, 3]}

A = pd.DataFrame(A)
B = pd.DataFrame(B)
user country order
0 a UK 1
1 b US 2
2 c US 2
3 d UK 4
4 e UK 4
5 f US 4
user country order
0 a US 2
1 b US 2
2 c UK 3
3 d FR 3
4 e UK 3
5 f US 3

I am trying to plot this data in such a way that I can see number of users vs number of orders. And also show the (unique) countries related to the order group when I navigate to the bar on plot (pass these countries to hovertemplate function?). I can get list of lists with unique countries of each order group (country_list), but I am struggling to pass the correct list of countries separately to each corresponding bar. Like in the highlighted plot (dataframe:B, order group: 3, number of users: 4) I want it to display unique countries: ['US', 'UK', 'FR'] related to that order group . Can anyone help with it?

data_dict = {"A" : A, "B": B}

fig = go.Figure()

for i in data_dict:
    tmp = data_dict[i]
    X = tmp["order"].value_counts().keys()
    Y = tmp["order"].value_counts().to_list()
    country_list = [tmp[tmp['order']==k]['country'].unique().tolist() for k in X]
    fig = fig.add_trace(go.Bar(x = X,
                               y = Y, 
                               hovertemplate='Users: %s' % (country_list),
                               name = i))
    
fig['layout']['yaxis']['title']='Users Count'
fig.update_xaxes(title='Orders')
fig.update_layout(height=500, width=1000)
fig.update_traces(texttemplate='%{y}', textposition='outside')

Like currently it displays the whole list of unique country lists regardless of order group: enter image description here

enter image description here

But I want it to display only the list of countries specific to that order group:

enter image description here

CodePudding user response:

To get the hover templates as you need, please change the hovertemplate line to this...

hovertemplate="Users: %{text}", text = country_list,

A bit more explanation - the country_list is a list of lists. For hovertemplate, it is expecting a list for each add_trace. The code is expected in the format mentioned above. Adding just (country_list) was causing the issue. Full updated code and working screenshot below.

import plotly.graph_objects as go
A = {
    'user': ['a', 'b', 'c', 'd', 'e', 'f'],
    'country': ['UK', 'US', 'US', 'UK', 'UK', 'US'],
    'order': [1, 2, 2, 4, 4, 4]}
B = {
    'user': ['a', 'b', 'c', 'd', 'e', 'f'],
    'country': ['US', 'US', 'UK', 'FR', 'UK', 'US'],
    'order': [2, 2, 3, 3, 3, 3]}

A = pd.DataFrame(A)
B = pd.DataFrame(B)
data_dict = {"A" : A, "B": B}

fig = go.Figure()

for i in data_dict:
    tmp = data_dict[i]
    X = tmp["order"].value_counts().keys()
    Y = tmp["order"].value_counts().to_list()
    country_list = [tmp[tmp['order']==k]['country'].unique().tolist() for k in X]
    fig = fig.add_trace(go.Bar(x = X, y = Y, 
                               hovertemplate="Users: %{text}", text = country_list,
                               name = i))    
fig['layout']['yaxis']['title']='Users Count'
fig.update_xaxes(title='Orders')
fig.update_layout(height=500, width=1000)
fig.update_traces(texttemplate='%{y}', textposition='outside')

Output screenshots

enter image description here

  • Related