Py.Cafe

banana0000/

Nutritional Content & Price by Category

with import plotly.graph_objs as go

DocsPricing
  • GroceryDB_foods.csv
  • app.py
  • requirements.txt
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
from dash import Dash, dcc, html, Input, Output, callback, dash_table
import pandas as pd
import plotly.graph_objs as go
import dash_ag_grid as dag

# Load the CSV file
df = pd.read_csv('GroceryDB_foods.csv')

# Strip spaces from column names
df.columns = df.columns.str.strip()

# Rename for easier access
df.rename(columns={'harmonized single category': 'category'}, inplace=True)

# Drop rows where category is missing
df = df.dropna(subset=['category'])

# Calculate per 100g values for each food item
category_summary = df.groupby('category').agg({
    'Protein': 'mean',     
    'Carbohydrate': 'mean',
    'Total Fat': 'mean',
    'price': 'mean'
}).reset_index()

# Merge category averages with original data
df = df.merge(category_summary, on='category', suffixes=('', '_avg'))

# Create Dash app
app = Dash(__name__)

# Get unique categories for dropdown
all_categories = category_summary['category'].unique()

# Layout
app.layout = html.Div([
    html.H1("๐Ÿ” Nutritional Content & Price by Category ๐Ÿฅ—", style={'textAlign': 'center', 'color': '#333'}),
    
    html.Div([
        html.Label("Select Categories:", style={'fontSize': '16px', 'fontWeight': 'bold'}),
        dcc.Dropdown(
            id='category-dropdown',
            options=[{'label': cat, 'value': cat} for cat in all_categories],
            value=all_categories[:5].tolist(),  # Default to first 5 categories
            multi=True
        )
    ], style={'width': '70%', 'margin': '20px auto'}),
    
    dcc.Graph(id='nutrition-price-graph', style={'height': '600px'}),
    
    html.H2("Detailed Product Data", style={'textAlign': 'center', 'marginTop': '20px'}),
    dag.AgGrid(
        id='data-table',
        columnDefs=[
            {'headerName': 'Product Name', 'field': 'name'},
            {'headerName': 'Category', 'field': 'category'},
            {'headerName': 'Protein (g)', 'field': 'Protein'},
            {'headerName': 'Carbohydrates (g)', 'field': 'Carbohydrate'},
            {'headerName': 'Total Fat (g)', 'field': 'Total Fat'},
            {'headerName': 'Price (USD)', 'field': 'price'},
            #{'headerName': 'Avg Protein (g)', 'field': 'Protein_avg'},
            #{'headerName': 'Avg Carbohydrates (g)', 'field': 'Carbohydrate_avg'},
            #{'headerName': 'Avg Total Fat (g)', 'field': 'Total Fat_avg'},
            #{'headerName': 'Avg Price (USD)', 'field': 'price_avg'}
        ],
        rowData=[],
        defaultColDef={'sortable': True, 'filter': True, 'resizable': True},
        style={'height': '400px', 'width': '90%', 'margin': 'auto'}
    )
])

@callback(
    Output('nutrition-price-graph', 'figure'),
    Output('data-table', 'rowData'),
    Input('category-dropdown', 'value')
)
def update_graph_and_table(selected_categories):
    if not selected_categories:
        selected_categories = all_categories[:5].tolist()
    
    filtered_data = category_summary[category_summary['category'].isin(selected_categories)]
    filtered_products = df[df['category'].isin(selected_categories)][['category', 'name', 'Protein', 'Carbohydrate', 'Total Fat', 'price', 'Protein_avg', 'Carbohydrate_avg', 'Total Fat_avg', 'price_avg']].to_dict('records')
    
    fig = go.Figure()
    
    fig.add_trace(go.Bar(
        y=filtered_data['category'],
        x=filtered_data['Protein'],
        name='Protein',
        marker=dict(color='#410445'),
        orientation='h'
    ))
    
    fig.add_trace(go.Bar(
        y=filtered_data['category'],
        x=filtered_data['Carbohydrate'],
        name='Carbohydrates',
        marker=dict(color='#A5158C'),
        orientation='h'
    ))
    
    fig.add_trace(go.Bar(
        y=filtered_data['category'],
        x=filtered_data['Total Fat'],
        name='Total Fat',
        marker=dict(color='#FF2DF1'),
        orientation='h'
    ))
    
    fig.add_trace(go.Scatter(
        y=filtered_data['category'],
        x=filtered_data['price'],
        mode='markers',
        name='Average Price',
        xaxis='x2',
        marker=dict(color='gold', size=35, symbol='circle')
    ))
    
    fig.update_layout(
        title='Nutritional Content & Price by Category',
        xaxis={'title': 'Nutritional Value (g/100g)'},
        xaxis2={'title': 'Average Price (USD)', 'overlaying': 'x', 'side': 'top'},
        barmode='stack',
        showlegend=True,
        paper_bgcolor='white',
        plot_bgcolor='white'
    )
    
    return fig, filtered_products

if __name__ == '__main__':
    app.run(debug=True)