rufimelo commited on
Commit
41173b4
·
1 Parent(s): 27206f0
.DS_Store ADDED
Binary file (6.15 kB). View file
 
Dockerfile ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10
2
+ # Set up a new user named "user" with user ID 1000
3
+ RUN useradd -m -u 1000 user
4
+
5
+ # Switch to the "user" user
6
+ USER user
7
+ # Set home to the user's home directory
8
+ ENV HOME=/home/user \
9
+ PATH=/home/user/.local/bin:$PATH
10
+
11
+ # Set the working directory to the user's home directory
12
+ WORKDIR $HOME/app
13
+
14
+ # Copy the current directory contents into the container at $HOME/app setting the owner to the user
15
+ COPY --chown=user ./app $HOME/app
16
+
17
+
18
+ ENV DASH_DEBUG_MODE False
19
+ #COPY ./app /app
20
+ #WORKDIR /app
21
+ RUN set -ex && \
22
+ pip install -r requirements.txt
23
+ EXPOSE 8050
24
+ CMD ["gunicorn", "-b", "0.0.0.0:8050", "--reload", "app:server"]
Dockerfile.dev ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10
2
+
3
+ ENV DASH_DEBUG_MODE True
4
+ COPY ./app /app
5
+ WORKDIR /app
6
+ RUN set -ex && \
7
+ pip install -r requirements.txt
8
+ EXPOSE 8050
9
+ CMD ["python", "app.py"]
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Jucy Technologies, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
README.md CHANGED
@@ -1,11 +1,50 @@
1
  ---
2
- title: Showcase
3
  emoji: 📈
4
- colorFrom: green
5
- colorTo: blue
6
  sdk: docker
7
- pinned: false
8
- license: mit
9
  ---
 
10
 
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Tour de Vino Showcase
3
  emoji: 📈
4
+ colorFrom: purple
5
+ colorTo: gray
6
  sdk: docker
7
+ app_port: 8050
 
8
  ---
9
+ # Docker Dash (Plotly)
10
 
11
+ Dockerize a Python Dash app for quick prototyping.
12
+
13
+ ## Build and run
14
+
15
+ `prod` version is served by `gunicorn` instead of the `flask` dev server.
16
+
17
+ ```sh
18
+ # dev
19
+ docker build -f Dockerfile.dev -t docker-dash-example-dev .
20
+ docker run -p 8050:8050 -v "$(pwd)"/app:/app --rm docker-dash-example-dev
21
+
22
+ # prod
23
+ docker build -f Dockerfile -t docker-dash-example-prod .
24
+ docker run -p 8050:8050 -v "$(pwd)"/app:/app --rm docker-dash-example-prod
25
+ ```
26
+
27
+ ## Access the page
28
+
29
+ Go to `http://localhost:8050` in browser.
30
+
31
+ ## Switch debug mode in Dockerfile
32
+
33
+ ```dockerfile
34
+ ENV DASH_DEBUG_MODE True # False
35
+ ```
36
+
37
+ ## Development
38
+
39
+ Install the app requirements for development to get better editor support.
40
+
41
+ ```sh
42
+ poetry install
43
+ ```
44
+
45
+ Optional: clean initialization of `poetry`:
46
+
47
+ ```sh
48
+ poetry init
49
+ cat app/requirements.txt | xargs poetry add
50
+ ```
app/.DS_Store ADDED
Binary file (6.15 kB). View file
 
app/__pycache__/core.cpython-310.pyc ADDED
Binary file (1.77 kB). View file
 
app/__pycache__/example_data.cpython-310.pyc ADDED
Binary file (2.4 kB). View file
 
app/app.py ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import plotly.express as px
3
+ import plotly.graph_objects as go
4
+ import pandas as pd
5
+ from dash import Dash, html, dcc, Input, Output, callback
6
+ import plotly.express as px
7
+ import numpy as np
8
+ from plotly.subplots import make_subplots
9
+
10
+ df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder_unfiltered.csv')
11
+
12
+ debug = False
13
+
14
+ external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
15
+
16
+ app = Dash(__name__, external_stylesheets=external_stylesheets)
17
+
18
+ app.layout = html.Div([
19
+ dcc.Location(id='url', refresh=False),
20
+ html.Div(id='page-content')
21
+ ])
22
+
23
+ server = app.server
24
+
25
+
26
+ dashboard_layout = html.Div([
27
+ dcc.Link('About this project', href='/wiki'),
28
+
29
+ html.H1(children='Title of Dash App', style={'textAlign':'center'}),
30
+ dcc.Dropdown(df.country.unique(), 'Canada', id='dropdown-selection'),
31
+ dcc.Graph(id='graph-content')
32
+
33
+ ])
34
+
35
+
36
+
37
+ wiki_layout = html.Div([
38
+ dcc.Link('Dashboard', href='/'),
39
+
40
+ html.H1('About this project'),
41
+
42
+ html.Div([
43
+ html.Div([
44
+
45
+ html.H3('What is this project about?'),
46
+
47
+ html.P('something'),
48
+
49
+ html.H3('How does it work?'),
50
+
51
+ #Insert image of the system
52
+
53
+ html.H3('\'Bout us'),
54
+ html.Img(src='/assets/tourdevino_logo.webp', style={'width': '40%', 'height': 'auto', 'display': 'block', 'margin-left': 'auto', 'margin-right': 'auto'}),
55
+ html.P('This project was developed by a team of 4, in the context of the SOGRAPE 2024 hackathon.'),
56
+ html.P('The team members are:'),
57
+ html.H4('Rui Melo'),
58
+ html.H4('André Catarino'),
59
+ html.H4('Dinis Costa'),
60
+ html.H4('Paulo Fidalgo'),
61
+
62
+
63
+
64
+ html.H3('References'),
65
+ html.P('The boiler model was based on the following paper:'),
66
+
67
+
68
+ ], className='six columns'),], className='row'),
69
+ ],
70
+ style={'background-color': '#333', 'font-family': 'Fantasy', 'color': '#999', 'padding': '10px'}
71
+
72
+ )
73
+
74
+ # Update the index
75
+ @callback(Output('page-content', 'children'), Input('url', 'pathname'))
76
+ def display_page(pathname):
77
+ if pathname == '/':
78
+ return dashboard_layout
79
+ elif pathname == '/wiki':
80
+ return wiki_layout
81
+ else:
82
+ return '404'
83
+ # You could also return a 404 "URL not found" page here
84
+
85
+
86
+ @app.callback(
87
+ Output('graph-content', 'figure'),
88
+ Input('dropdown-selection', 'value')
89
+ )
90
+ def update_graph(value):
91
+ dff = df[df.country==value]
92
+ return px.line(dff, x='year', y='pop')
93
+
94
+
95
+ if __name__ == "__main__":
96
+ app.run_server(host="0.0.0.0", port="8050", debug=debug)
app/assets/.DS_Store ADDED
Binary file (6.15 kB). View file
 
app/assets/tourdevino_logo.webp ADDED
app/core.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Electric cost(Euros) = energy_price(Euros/kWh) * wasted_energy(kWh)
2
+ def custo(energy_price_hour, wasted_energy):
3
+ return energy_price_hour * wasted_energy
4
+
5
+
6
+ # caldeira 20 litros
7
+ def spent_energy(
8
+ temperatura_inicial_caldeira_t, # existente na cadeira, t sendo a hora
9
+ temperatura_objetivo_caldeira_t_plus_1,
10
+ outside_temp,
11
+ pressao_caldeira,
12
+ litros_gastos_no_banho=0,
13
+ temperatura_entrada_agua_na_caldeira=15, # Temperatura ambiente da iNOVA
14
+ capacidade_caldeira=20, # 20 litros
15
+ ):
16
+ # E = (4.2 kJ/kgoC) ((90 oC) - (20 oC)) (1000 liter) (1 kg/liter)
17
+ # cp = specific heat of water (kJ/kgoC, Btu/lb oF) (4.2 kJ/kgoC, 1 Btu/lbmoF for water)
18
+ heat_capacity = 4.2
19
+ # Energy = heat_capacity * (temperatura_saida_agua_na_caldeira - outside_temp) * capacidade_caldeira * 1\
20
+ delta_t = temperatura_objetivo_caldeira_t_plus_1 - temperatura_inicial_caldeira_t
21
+
22
+ energy = (
23
+ heat_capacity
24
+ * (delta_t - outside_temp)
25
+ * (capacidade_caldeira - litros_gastos_no_banho)
26
+ * 1
27
+ ) # isto vai ser minimo
28
+
29
+ delta_t = (
30
+ temperatura_objetivo_caldeira_t_plus_1 - temperatura_entrada_agua_na_caldeira
31
+ )
32
+ energy_incoming_water = (
33
+ heat_capacity * (delta_t - outside_temp) * litros_gastos_no_banho * 1
34
+ )
35
+
36
+ # 20 Litros totais
37
+ # Joao gatou 5 litros
38
+ # Gastar energia em:
39
+ # 15 litros para manter a temperatura da caldeira -> minimo
40
+ # 5 litros para aquecer a agua que entra
41
+
42
+ total_energy = energy + energy_incoming_water
43
+
44
+ # TODO: Correlação entre pressão e temperatura
45
+ # https://www.engineeringtoolbox.com/boiling-points-water-altitude-d_1344.html
46
+ # https://www.engineeringtoolbox.com/boiling-point-water-d_926.html
47
+ """
48
+ That depends on whether the pressure is held constant during the heating. If there is a relief valve which maintains
49
+ constant pressure as the water heats, then no, the 2 samples will heat at the same rate. However, if the pressurised sample
50
+ has no pressure relief, then it will heat faster because the pressure will increase, and that increase in pressure will increase
51
+ the heat in addition to the heat applied.
52
+ """
53
+ # kJ
54
+
55
+ # TODO: FIND WHAT SHOULD BE THE RELATION BETWEEN TEMPERATURE OF OUTGOING WATER AND BOILER TEMPERATURE
56
+ temperatura_saida_agua_na_caldeira = temperatura_objetivo_caldeira_t_plus_1 * 0.87
57
+
58
+ return total_energy, temperatura_saida_agua_na_caldeira
59
+
60
+
61
+ def calculate_weights_for_all_hours(
62
+ temperatura_inicial_caldeira,
63
+ temperatura_objetivo_caldeira,
64
+ outside_temp,
65
+ pressao_caldeira,
66
+ litros_gastos_no_banho,
67
+ temperatura_entrada_agua_na_caldeira,
68
+ capacidade_caldeira,
69
+ ):
70
+ weights = []
71
+ temperatures = []
72
+ for i in range(len(temperatura_inicial_caldeira)):
73
+ energy, temperature_water = spent_energy(
74
+ temperatura_inicial_caldeira_t=temperatura_inicial_caldeira[i],
75
+ temperatura_objetivo_caldeira_t_plus_1=temperatura_objetivo_caldeira,
76
+ outside_temp=outside_temp[i],
77
+ pressao_caldeira=pressao_caldeira[i],
78
+ litros_gastos_no_banho=litros_gastos_no_banho,
79
+ temperatura_entrada_agua_na_caldeira=temperatura_entrada_agua_na_caldeira[
80
+ i
81
+ ],
82
+ capacidade_caldeira=capacidade_caldeira,
83
+ )
84
+ weights.append(energy)
85
+ temperatures.append(temperature_water)
86
+ return weights, temperatures
87
+ # Output energy wasted
88
+
89
+
90
+ def calculate_confort(temperatura_given, temperatura_ideal):
91
+ return abs(temperatura_given - temperatura_ideal)
92
+
93
+
94
+ # create exception for no solution found
95
+ class NoSolutionFound(Exception):
96
+ pass
97
+
98
+ class SoltionFoundWithLargerConfortValue(Exception):
99
+ pass
app/dashboard.ipynb ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 27,
6
+ "metadata": {},
7
+ "outputs": [
8
+ {
9
+ "data": {
10
+ "text/html": [
11
+ "\n",
12
+ " <iframe\n",
13
+ " width=\"100%\"\n",
14
+ " height=\"650\"\n",
15
+ " src=\"http://0.0.0.0:8050/\"\n",
16
+ " frameborder=\"0\"\n",
17
+ " allowfullscreen\n",
18
+ " \n",
19
+ " ></iframe>\n",
20
+ " "
21
+ ],
22
+ "text/plain": [
23
+ "<IPython.lib.display.IFrame at 0x2a29674c0>"
24
+ ]
25
+ },
26
+ "metadata": {},
27
+ "output_type": "display_data"
28
+ }
29
+ ],
30
+ "source": [
31
+ "import os\n",
32
+ "import plotly.express as px\n",
33
+ "import plotly.graph_objects as go\n",
34
+ "import pandas as pd\n",
35
+ "from dash import Dash, html, dcc, Input, Output, callback\n",
36
+ "import plotly.express as px\n",
37
+ "import numpy as np\n",
38
+ "from plotly.subplots import make_subplots\n",
39
+ "\n",
40
+ "df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder_unfiltered.csv')\n",
41
+ "\n",
42
+ "debug = False\n",
43
+ "\n",
44
+ "external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']\n",
45
+ "\n",
46
+ "app = Dash(__name__, external_stylesheets=external_stylesheets)\n",
47
+ "\n",
48
+ "app.layout = html.Div([\n",
49
+ " dcc.Location(id='url', refresh=False),\n",
50
+ " html.Div(id='page-content')\n",
51
+ "])\n",
52
+ "\n",
53
+ "server = app.server\n",
54
+ "\n",
55
+ "\n",
56
+ "dashboard_layout = html.Div([\n",
57
+ " dcc.Link('About this project', href='/wiki'),\n",
58
+ "\n",
59
+ " html.H1(children='Title of Dash App', style={'textAlign':'center'}),\n",
60
+ " dcc.Dropdown(df.country.unique(), 'Canada', id='dropdown-selection'),\n",
61
+ " dcc.Graph(id='graph-content')\n",
62
+ "\n",
63
+ "])\n",
64
+ "\n",
65
+ "\n",
66
+ "\n",
67
+ "wiki_layout = html.Div([\n",
68
+ " dcc.Link('Dashboard', href='/'),\n",
69
+ "\n",
70
+ " html.H1('About this project'),\n",
71
+ "\n",
72
+ " html.Div([\n",
73
+ " html.Div([\n",
74
+ "\n",
75
+ " html.H3('What is this project about?'),\n",
76
+ "\n",
77
+ " html.P('This project is a simulation of a shower system. The goal is to find the best policy for the boiler to heat the water for the shower. The policy is a function that takes the current hour of the day and the current temperature of the water in the boiler and returns the temperature that the boiler should heat the water to.'),\n",
78
+ " html.P('The best policy is the one that maximizes the comfort of the shower and minimizes the energy consumption of the boiler.'),\n",
79
+ "\n",
80
+ " html.H3('How does it work?'),\n",
81
+ "\n",
82
+ " #Insert image of the system\n",
83
+ "\n",
84
+ " html.H3('\\'Bout us'),\n",
85
+ " html.Img(src='/assets/tourdevino_logo.webp', style={'width': '40%', 'height': 'auto', 'display': 'block', 'margin-left': 'auto', 'margin-right': 'auto'}),\n",
86
+ " html.P('This project was developed by a team of 3, in the context of the Aveiro Tech City 2023 hackathon.'),\n",
87
+ " html.P('The team members are:'),\n",
88
+ " html.H4('Rui Melo'),\n",
89
+ " html.H4('André Catarino'),\n",
90
+ " html.H4('Dinis Costa'),\n",
91
+ " html.H4('Paulo Fidalgo'),\n",
92
+ " \n",
93
+ "\n",
94
+ "\n",
95
+ " html.H3('References'),\n",
96
+ " html.P('The boiler model was based on the following paper:'),\n",
97
+ "\n",
98
+ "\n",
99
+ " ], className='six columns'),], className='row'),\n",
100
+ "],\n",
101
+ "style={'background-color': '#333', 'font-family': 'Fantasy', 'color': '#999', 'padding': '10px'}\n",
102
+ "\n",
103
+ ")\n",
104
+ "\n",
105
+ "# Update the index\n",
106
+ "@callback(Output('page-content', 'children'), Input('url', 'pathname'))\n",
107
+ "def display_page(pathname):\n",
108
+ " if pathname == '/':\n",
109
+ " return dashboard_layout\n",
110
+ " elif pathname == '/wiki':\n",
111
+ " return wiki_layout\n",
112
+ " else:\n",
113
+ " return '404'\n",
114
+ " # You could also return a 404 \"URL not found\" page here\n",
115
+ "\n",
116
+ "\n",
117
+ "@app.callback(\n",
118
+ " Output('graph-content', 'figure'),\n",
119
+ " Input('dropdown-selection', 'value')\n",
120
+ ")\n",
121
+ "def update_graph(value):\n",
122
+ " dff = df[df.country==value]\n",
123
+ " return px.line(dff, x='year', y='pop')\n",
124
+ "\n",
125
+ "\n",
126
+ "if __name__ == \"__main__\":\n",
127
+ " app.run_server(host=\"0.0.0.0\", port=\"8050\", debug=debug)"
128
+ ]
129
+ },
130
+ {
131
+ "cell_type": "code",
132
+ "execution_count": null,
133
+ "metadata": {},
134
+ "outputs": [],
135
+ "source": []
136
+ },
137
+ {
138
+ "cell_type": "code",
139
+ "execution_count": null,
140
+ "metadata": {},
141
+ "outputs": [],
142
+ "source": []
143
+ }
144
+ ],
145
+ "metadata": {
146
+ "kernelspec": {
147
+ "display_name": "atc-smart-shower-YhjpRjjr-py3.10",
148
+ "language": "python",
149
+ "name": "python3"
150
+ },
151
+ "language_info": {
152
+ "codemirror_mode": {
153
+ "name": "ipython",
154
+ "version": 3
155
+ },
156
+ "file_extension": ".py",
157
+ "mimetype": "text/x-python",
158
+ "name": "python",
159
+ "nbconvert_exporter": "python",
160
+ "pygments_lexer": "ipython3",
161
+ "version": "3.10.14"
162
+ },
163
+ "orig_nbformat": 4
164
+ },
165
+ "nbformat": 4,
166
+ "nbformat_minor": 2
167
+ }
app/data/.DS_Store ADDED
Binary file (6.15 kB). View file
 
app/requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ dash
2
+ plotly
3
+ pandas
4
+ gunicorn
5
+ wandb==0.15.5
6
+ scipy
dashboard.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+
3
+ data = pd.DataFrame(columns=["Dataset", "Alpha", "Top K", "Recall", "Precision"])
4
+ data = pd.concat(
5
+ [
6
+ data,
7
+ pd.DataFrame(
8
+ [["ml-100k", 0.1, 20, 0.2, 0.2]],
9
+ columns=["Dataset", "Alpha", "Top K", "Recall", "Precision"],
10
+ ),
11
+ ]
12
+ )
13
+
14
+ import os
15
+ import plotly.express as px
16
+ import pandas as pd
17
+ from dash import Dash, html, dcc, Input, Output, callback
18
+ import plotly.express as px
19
+ from dataclasses import dataclass
20
+ import json
21
+
22
+ data = pd.DataFrame(columns=["Dataset", "Alpha", "Top K", "Recall", "Precision"])
23
+ data = pd.concat(
24
+ [
25
+ data,
26
+ pd.DataFrame(
27
+ [["ml-100k", 0.1, 20, 0.2, 0.2]],
28
+ columns=["Dataset", "Alpha", "Top K", "Recall", "Precision"],
29
+ ),
30
+ ]
31
+ )
32
+ debug = False
33
+
34
+
35
+ external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
36
+
37
+ app = Dash(__name__, external_stylesheets=external_stylesheets)
38
+
39
+ server = app.server
40
+
41
+
42
+ dataset_options = [
43
+ {"label": entry, "value": entry} for entry in data["Dataset"].unique()
44
+ ]
45
+ dataset_options_default_value = data["Dataset"].unique()[0]
46
+
47
+ alpha_options = [{"label": entry, "value": entry} for entry in data["Alpha"].unique()]
48
+ alpha_options_default_value = data["Alpha"].unique()[0]
49
+
50
+ top_k_options = [{"label": entry, "value": entry} for entry in data["Top K"].unique()]
51
+ top_k_options_default_value = data["Top K"].unique()[0]
52
+
53
+ app.layout = html.Div(
54
+ [
55
+ html.H1("System Evaluation"),
56
+ html.Div(
57
+ [
58
+ html.Div(
59
+ [
60
+ html.H3("Dataset"),
61
+ dcc.Dropdown(
62
+ id="dataset-dropdown",
63
+ options=dataset_options,
64
+ value=dataset_options_default_value,
65
+ ),
66
+ ],
67
+ className="three columns",
68
+ ),
69
+ html.Div(
70
+ [
71
+ html.H3("Alpha"),
72
+ dcc.Dropdown(
73
+ id="alpha-dropdown",
74
+ options=alpha_options,
75
+ value=alpha_options_default_value,
76
+ ),
77
+ ],
78
+ className="three columns",
79
+ ),
80
+ html.Div(
81
+ [
82
+ html.H3("Top K"),
83
+ dcc.Dropdown(
84
+ id="top_k-dropdown",
85
+ options=top_k_options,
86
+ value=top_k_options_default_value,
87
+ ),
88
+ ],
89
+ className="three columns",
90
+ ),
91
+ ],
92
+ className="row",
93
+ ),
94
+ html.Div(
95
+ [
96
+ html.Div([dcc.Graph(id="recall-graph")], className="six columns"),
97
+ html.Div([dcc.Graph(id="precision-graph")], className="six columns"),
98
+ ],
99
+ className="row",
100
+ ),
101
+ ]
102
+ )
103
+
104
+
105
+ @app.callback(
106
+ Output("recall-graph", "figure"),
107
+ Output("precision-graph", "figure"),
108
+ Input("alpha-dropdown", "value"),
109
+ Input("dataset-dropdown", "value"),
110
+ Input("top_k-dropdown", "value"),
111
+ )
112
+ def update_graph(alpha, dataset, top_k):
113
+ filtered_data = data[
114
+ (data["Alpha"] == alpha)
115
+ & (data["Dataset"] == dataset)
116
+ & (data["Top K"] == top_k)
117
+ ]
118
+ recall_fig = px.bar(filtered_data, x="Dataset", y="Recall")
119
+ precision_fig = px.bar(filtered_data, x="Dataset", y="Precision")
120
+ return recall_fig, precision_fig
121
+
122
+
123
+ # Run app and display result inline in the notebook
124
+ if __name__ == "__main__":
125
+ app.run_server(debug=debug, port=8050)