lunadebruyne commited on
Commit
ab937a1
Β·
1 Parent(s): 5695706

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +414 -0
app.py ADDED
@@ -0,0 +1,414 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import numpy as np
4
+ import pickle
5
+
6
+ import pandas as pd
7
+ from tqdm import tqdm
8
+
9
+ import altair as alt
10
+ import matplotlib.pyplot as plt
11
+ from datetime import date, timedelta
12
+
13
+ from transformers import AutoTokenizer, AutoConfig, AutoModel, AutoModelForSequenceClassification
14
+
15
+ """
16
+ description_sentence = "<h3>Demo EmotioNL</h3>\nThis demo allows you to analyse the emotion in a sentence."
17
+ description_dataset = "<h3>Demo EmotioNL</h3>\nThis demo allows you to analyse the emotions in a dataset.\nThe data should be in tsv-format with two named columns: the first column (id) should contain the sentence IDs, and the second column (text) should contain the actual texts. Optionally, there is a third column named 'date', which specifies the date associated with the text (e.g., tweet date). This column is necessary when the options 'emotion distribution over time' and 'peaks' are selected."
18
+ inference_modelpath = "model/checkpoint-128"
19
+ def inference_sentence(text):
20
+ tokenizer = AutoTokenizer.from_pretrained(inference_modelpath)
21
+ model = AutoModelForSequenceClassification.from_pretrained(inference_modelpath)
22
+ for text in tqdm([text]):
23
+ inputs = tokenizer(text, return_tensors="pt")
24
+ with torch.no_grad(): # run model
25
+ logits = model(**inputs).logits
26
+ predicted_class_id = logits.argmax().item()
27
+ output = model.config.id2label[predicted_class_id]
28
+ return output
29
+ def frequencies(preds):
30
+ preds_dict = {"neutral": 0, "anger": 0, "fear": 0, "joy": 0, "love": 0, "sadness": 0}
31
+ for pred in preds:
32
+ preds_dict[pred] = preds_dict[pred] + 1
33
+ bars = list(preds_dict.keys())
34
+ height = list(preds_dict.values())
35
+ x_pos = np.arange(len(bars))
36
+ plt.bar(x_pos, height, color=['lightgrey', 'firebrick', 'rebeccapurple', 'orange', 'palevioletred', 'cornflowerblue'])
37
+ plt.xticks(x_pos, bars)
38
+ return plt
39
+
40
+ def inference_dataset(file_object, option_list):
41
+ tokenizer = AutoTokenizer.from_pretrained(inference_modelpath)
42
+ model = AutoModelForSequenceClassification.from_pretrained(inference_modelpath)
43
+ data_path = open(file_object.name, 'r')
44
+ df = pd.read_csv(data_path, delimiter='\t', header=0, names=['id', 'text'])
45
+ ids = df["id"].tolist()
46
+ texts = df["text"].tolist()
47
+ preds = []
48
+ for text in tqdm(texts): # progressbar
49
+ inputs = tokenizer(text, return_tensors="pt")
50
+ with torch.no_grad(): # run model
51
+ logits = model(**inputs).logits
52
+ predicted_class_id = logits.argmax().item()
53
+ prediction = model.config.id2label[predicted_class_id]
54
+ preds.append(prediction)
55
+ predictions_content = list(zip(ids, texts, preds))
56
+ # write predictions to file
57
+ output = "output.txt"
58
+ f = open(output, 'w')
59
+ f.write("id\ttext\tprediction\n")
60
+ for line in predictions_content:
61
+ f.write(str(line[0]) + '\t' + str(line[1]) + '\t' + str(line[2]) + '\n')
62
+ output1 = output
63
+ output2 = output3 = output4 = output5 = "This option was not selected."
64
+ if "emotion frequencies" in option_list:
65
+ output2 = frequencies(preds)
66
+ else:
67
+ output2 = None
68
+ if "emotion distribution over time" in option_list:
69
+ output3 = "This option was selected."
70
+ if "peaks" in option_list:
71
+ output4 = "This option was selected."
72
+ if "topics" in option_list:
73
+ output5 = "This option was selected."
74
+ return [output1, output2, output3, output4, output5]
75
+ iface_sentence = gr.Interface(
76
+ fn=inference_sentence,
77
+ description = description_sentence,
78
+ inputs = gr.Textbox(
79
+ label="Enter a sentence",
80
+ lines=1),
81
+ outputs="text")
82
+ inputs = [gr.File(
83
+ label="Upload a dataset"),
84
+ gr.CheckboxGroup(
85
+ ["emotion frequencies", "emotion distribution over time", "peaks", "topics"],
86
+ label = "Select options")]
87
+ outputs = [gr.File(),
88
+ gr.Plot(label="Emotion frequencies"),
89
+ gr.Textbox(label="Emotion distribution over time"),
90
+ gr.Textbox(label="Peaks"),
91
+ gr.Textbox(label="Topics")]
92
+ iface_dataset = gr.Interface(
93
+ fn = inference_dataset,
94
+ description = description_dataset,
95
+ inputs=inputs,
96
+ outputs = outputs)
97
+ iface = gr.TabbedInterface([iface_sentence, iface_dataset], ["Sentence", "Dataset"])
98
+ iface.queue().launch()
99
+ """
100
+
101
+ inference_modelpath = "model/checkpoint-128"
102
+
103
+ def inference_sentence(text):
104
+ tokenizer = AutoTokenizer.from_pretrained(inference_modelpath)
105
+ model = AutoModelForSequenceClassification.from_pretrained(inference_modelpath)
106
+ for text in tqdm([text]):
107
+ inputs = tokenizer(text, return_tensors="pt")
108
+ with torch.no_grad(): # run model
109
+ logits = model(**inputs).logits
110
+ predicted_class_id = logits.argmax().item()
111
+ output = model.config.id2label[predicted_class_id]
112
+ return "Predicted emotion:\n" + output
113
+ """
114
+ def inference_sentence(text):
115
+ output = "This sentence will be processed:\n" + text
116
+ return output
117
+ """
118
+
119
+ def unavailable(input_file, input_checks):
120
+ output = "As we are currently updating this demo, submitting your own data is unavailable for the moment. However, you can try out the showcase mode 😊"
121
+ return gr.update(value=output, label="Oops!", visible=True)
122
+
123
+ def showcase(input_file):
124
+ output = "showcase/example_predictions.txt"
125
+ return gr.update(visible=False), gr.update(value=output, visible=True), gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False) # next_button_freq becomes available
126
+
127
+ def file(input_file, input_checks):
128
+ #output = "output.txt"
129
+ #f = open(output, 'w')
130
+ #f.write("The predictions come here.")
131
+ #f.close()
132
+ output = "showcase/example_predictions.txt"
133
+ if "emotion frequencies" in input_checks:
134
+ return gr.update(value=output, visible=True), gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False) # next_button_freq becomes available
135
+ elif "emotion distribution over time" in input_checks:
136
+ return gr.update(value=output, visible=True), gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update(visible=False) # next_button_dist becomes available
137
+ elif "peaks" in input_checks:
138
+ return gr.update(value=output, visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), gr.update(visible=False) # next_button_peaks becomes available
139
+ elif "topics" in input_checks:
140
+ return gr.update(value=output, visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=True) # next_button_topics becomes available
141
+ else:
142
+ return gr.update(value=output, visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False) # no next_button becomes available
143
+
144
+ def freq(output_file, input_checks):
145
+ #simple = pd.DataFrame({
146
+ #'Emotion category': ['neutral', 'anger', 'fear', 'joy', 'love', 'sadness'],
147
+ #'Frequency': [10, 8, 2, 15, 3, 4]})
148
+
149
+ f = open("showcase/example_predictions.txt", 'r')
150
+ data = f.read().split("\n")
151
+ f.close()
152
+ data = [line.split("\t") for line in data[1:-1]]
153
+
154
+ freq_dict = {}
155
+ for line in data:
156
+ if line[1] not in freq_dict.keys():
157
+ freq_dict[line[1]] = 1
158
+ else:
159
+ freq_dict[line[1]] += 1
160
+
161
+ simple = pd.DataFrame({
162
+ 'Emotion category': ['neutral', 'anger', 'fear', 'joy', 'love', 'sadness'],
163
+ 'Frequency': [freq_dict['neutral'], freq_dict['anger'], freq_dict['fear'], freq_dict['joy'], freq_dict['love'], freq_dict['sadness']]})
164
+
165
+ domain = ['neutral', 'anger', 'fear', 'joy', 'love', 'sadness']
166
+ range_ = ['#999999', '#b22222', '#663399', '#ffcc00', '#db7093', '#6495ed']
167
+ n = max(simple['Frequency'])
168
+
169
+ plot = alt.Chart(simple).mark_bar().encode(
170
+ x=alt.X("Emotion category", sort=['neutral', 'anger', 'fear', 'joy', 'love', 'sadness']),
171
+ y=alt.Y("Frequency", axis=alt.Axis(grid=False), scale=alt.Scale(domain=[0, (n + 9) // 10 * 10])),
172
+ color=alt.Color("Emotion category", scale=alt.Scale(domain=domain, range=range_), legend=None),
173
+ tooltip=['Emotion category', 'Frequency']).properties(
174
+ width=600).configure_axis(
175
+ grid=False).interactive()
176
+
177
+ if "emotion distribution over time" in input_checks or (output_file.name).startswith('/tmp/example_predictions'):
178
+ return gr.update(value=plot, visible=True), gr.update(visible=True), gr.update(visible=False), gr.update(visible=False) # next_button_dist becomes available
179
+ elif "peaks" in input_checks:
180
+ return gr.update(value=plot, visible=True), gr.update(visible=False), gr.update(visible=True), gr.update(visible=False) # next_button_peaks becomes available
181
+ elif "topics" in input_checks:
182
+ return gr.update(value=plot, visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(visible=True) # next_button_topics becomes available
183
+ else:
184
+ return gr.update(value=plot, visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False) # no next_button becomes available
185
+
186
+
187
+ def dist(output_file, input_checks):
188
+ #data = pd.DataFrame({
189
+ #'Date': ['1/1', '1/1', '1/1', '1/1', '1/1', '1/1', '2/1', '2/1', '2/1', '2/1', '2/1', '2/1', '3/1', '3/1', '3/1', '3/1', '3/1', '3/1'],
190
+ #'Frequency': [3, 5, 1, 8, 2, 3, 4, 7, 1, 12, 4, 2, 3, 6, 3, 10, 3, 4],
191
+ #'Emotion category': ['neutral', 'anger', 'fear', 'joy', 'love', 'sadness', 'neutral', 'anger', 'fear', 'joy', 'love', 'sadness', 'neutral', 'anger', 'fear', 'joy', 'love', 'sadness']})
192
+
193
+ f = open("showcase/data.txt", 'r')
194
+ data = f.read().split("\n")
195
+ f.close()
196
+ data = [line.split("\t") for line in data[1:-1]]
197
+
198
+ freq_dict = {}
199
+ for line in data:
200
+ dat = str(date(2000+int(line[0].split("/")[2]), int(line[0].split("/")[1]), int(line[0].split("/")[0])))
201
+ if dat not in freq_dict.keys():
202
+ freq_dict[dat] = {}
203
+ if line[1] not in freq_dict[dat].keys():
204
+ freq_dict[dat][line[1]] = 1
205
+ else:
206
+ freq_dict[dat][line[1]] += 1
207
+ else:
208
+ if line[1] not in freq_dict[dat].keys():
209
+ freq_dict[dat][line[1]] = 1
210
+ else:
211
+ freq_dict[dat][line[1]] += 1
212
+
213
+ start_date = date(2000+int(data[0][0].split("/")[2]), int(data[0][0].split("/")[1]), int(data[0][0].split("/")[0]))
214
+ end_date = date(2000+int(data[-1][0].split("/")[2]), int(data[-1][0].split("/")[1]), int(data[-1][0].split("/")[0]))
215
+ delta = end_date - start_date # returns timedelta
216
+ date_range = [str(start_date + timedelta(days=i)) for i in range(delta.days + 1)]
217
+
218
+ dates = [dat for dat in date_range for i in range(6)]
219
+ frequency = [freq_dict[dat][emotion] if (dat in freq_dict.keys() and emotion in freq_dict[dat].keys()) else 0 for dat in date_range for emotion in ['neutral', 'anger', 'fear', 'joy', 'love', 'sadness']]
220
+ categories = [emotion for dat in date_range for emotion in ['neutral', 'anger', 'fear', 'joy', 'love', 'sadness']]
221
+
222
+ data = pd.DataFrame({
223
+ 'Date': dates,
224
+ 'Frequency': frequency,
225
+ 'Emotion category': categories})
226
+
227
+ domain = ['neutral', 'anger', 'fear', 'joy', 'love', 'sadness']
228
+ range_ = ['#999999', '#b22222', '#663399', '#ffcc00', '#db7093', '#6495ed']
229
+ n = max(data['Frequency'])
230
+
231
+ highlight = alt.selection(
232
+ type='single', on='mouseover', fields=["Emotion category"], nearest=True)
233
+
234
+
235
+ base = alt.Chart(data).encode(
236
+ x ="Date:T",
237
+ y=alt.Y("Frequency", scale=alt.Scale(domain=[0, (n + 9) // 10 * 10])),
238
+ color=alt.Color("Emotion category", scale=alt.Scale(domain=domain, range=range_), legend=alt.Legend(orient='bottom', direction='horizontal')))
239
+
240
+
241
+ points = base.mark_circle().encode(
242
+ opacity=alt.value(0),
243
+ tooltip=[
244
+ alt.Tooltip('Emotion category', title='Emotion category'),
245
+ alt.Tooltip('Date:T', title='Date'),
246
+ alt.Tooltip('Frequency', title='Frequency')
247
+ ]).add_selection(highlight)
248
+
249
+
250
+ lines = base.mark_line().encode(
251
+ size=alt.condition(~highlight, alt.value(1), alt.value(3)))
252
+
253
+ plot = (points + lines).properties(width=600, height=350).interactive()
254
+
255
+ if "peaks" in input_checks or (output_file.name).startswith('/tmp/example_predictions'):
256
+ return gr.Plot.update(value=plot, visible=True), gr.update(visible=True), gr.update(visible=False) # next_button_peaks becomes available
257
+ elif "topics" in input_checks:
258
+ return gr.Plot.update(value=plot, visible=True), gr.update(visible=False), gr.update(visible=True) # next_button_topics becomes available
259
+ else:
260
+ return gr.Plot.update(value=plot, visible=True), gr.update(visible=False), gr.update(visible=False) # no next_button becomes available
261
+
262
+ def peaks(output_file, input_checks):
263
+ peaks_anger = {"9/2/2020": "up", "18/2/2020": "down", "8/3/2020": "up", "20/3/2020": "up", "31/5/2020": "up", "6/6/2020": "up", "19/6/2020": "up", "19/7/2020": "up"}
264
+ peaks_fear = {"8/2/2020": "up", "11/2/2020": "down", "31/5/2020": "down", "12/6/2020": "up", "5/7/2020": "up", "19/7/2020": "up"}
265
+ peaks_joy = {"13/3/2020": "up", "4/4/2020": "up", "19/6/2020": "up", "26/6/2020": "up"}
266
+ peaks_love = {"12/3/2020": "up", "5/5/2020": "down", "26/6/2020": "up", "7/8/2020": "up",}
267
+ peaks_sadness = {"14/2/2020": "up", "3/4/2020": "up", "5/5/2020": "down", "18/5/2020": "down", "30/6/2020": "up", "5/7/2020": "up"}
268
+
269
+ text_anger = ", ".join([str(key) + " (↑)" if value == "up" else str(key) + " (↓)" for key, value in peaks_anger.items()])
270
+ text_fear = ", ".join([str(key) + " (↑)" if value == "up" else str(key) + " (↓)" for key, value in peaks_fear.items()])
271
+ text_joy = ", ".join([str(key) + " (↑)" if value == "up" else str(key) + " (↓)" for key, value in peaks_joy.items()])
272
+ text_love = ", ".join([str(key) + " (↑)" if value == "up" else str(key) + " (↓)" for key, value in peaks_love.items()])
273
+ text_sadness = ", ".join([str(key) + " (↑)" if value == "up" else str(key) + " (↓)" for key, value in peaks_sadness.items()])
274
+
275
+ html = (
276
+ '<html>'
277
+ '<head>'
278
+ '<meta name="viewport" content="width=device-width, initial-scale=1">'
279
+ '<style>'
280
+ '.dot_neutral {'
281
+ 'height: 11px;'
282
+ 'width: 11px;'
283
+ 'background-color: #999999;'
284
+ 'border-radius: 50%;'
285
+ 'display: inline-block;'
286
+ '}'
287
+ '.dot_anger {'
288
+ 'height: 11px;'
289
+ 'width: 11px;'
290
+ 'background-color: #b22222;'
291
+ 'border-radius: 50%;'
292
+ 'display: inline-block;'
293
+ '}'
294
+ '.dot_fear {'
295
+ 'height: 11px;'
296
+ 'width: 11px;'
297
+ 'background-color: #663399;'
298
+ 'border-radius: 50%;'
299
+ 'display: inline-block;'
300
+ '}'
301
+ '.dot_joy {'
302
+ 'height: 11px;'
303
+ 'width: 11px;'
304
+ 'background-color: #ffcc00;'
305
+ 'border-radius: 50%;'
306
+ 'display: inline-block;'
307
+ '}'
308
+ '.dot_love {'
309
+ 'height: 11px;'
310
+ 'width: 11px;'
311
+ 'background-color: #db7093;'
312
+ 'border-radius: 50%;'
313
+ 'display: inline-block;'
314
+ '}'
315
+ '.dot_sadness {'
316
+ 'height: 11px;'
317
+ 'width: 11px;'
318
+ 'background-color: #6495ed;'
319
+ 'border-radius: 50%;'
320
+ 'display: inline-block;'
321
+ '}'
322
+ '.tab {'
323
+ 'padding-left: 1em;'
324
+ '}'
325
+ '</style>'
326
+ '</head>'
327
+ '<body>'
328
+ '<div>'
329
+ '<p>These significant fluctuations were found:</p>'
330
+ '<p><span class="dot_anger"></span> anger:</p>'
331
+ '<p class="tab">' + text_anger + '<p>'
332
+ '<p><span class="dot_fear"></span> fear:</p>'
333
+ '<p class="tab">' + text_fear + '<p>'
334
+ '<p><span class="dot_joy"></span> joy:</p>'
335
+ '<p class="tab">' + text_joy + '<p>'
336
+ '<p><span class="dot_love"></span> love:</p>'
337
+ '<p class="tab">' + text_love + '<p>'
338
+ '<p><span class="dot_sadness"></span> sadness:</p>'
339
+ '<p class="tab">' + text_sadness + '<p>'
340
+ '</div>'
341
+ '</body>'
342
+ '</html>'
343
+ )
344
+ if "topics" in input_checks or (output_file.name).startswith('/tmp/example_predictions'):
345
+ return gr.update(value=html, visible=True), gr.update(visible=True) # next_button_topics becomes available
346
+ else:
347
+ return gr.update(value=html, visible=True), gr.update(visible=False) # no next_button becomes available
348
+
349
+ def topics(output_file, input_checks):
350
+ plot = pickle.load(open('showcase/vis_classes_covid.p', 'rb'))
351
+ plot.update_layout(width=600, height=400)
352
+ return gr.Plot.update(value=plot, visible=True) # no next_button becomes available
353
+
354
+ with gr.Blocks() as demo:
355
+ with gr.Tab("Sentence"):
356
+ gr.Markdown("""
357
+ # Demo EmotioNL
358
+ This demo allows you to analyse the emotion in a Dutch sentence.
359
+ """)
360
+ with gr.Row():
361
+ with gr.Column():
362
+ input = gr.Textbox(
363
+ label="Enter a sentence",
364
+ value="Jaaah! Volgende vakantie Barcelona en na het zomerseizoen naar de Algarve",
365
+ lines=1)
366
+ send_btn = gr.Button("Send")
367
+ output = gr.Textbox()
368
+ send_btn.click(fn=inference_sentence, inputs=input, outputs=output)
369
+ with gr.Tab("Dataset"):
370
+ gr.Markdown("""
371
+ # Demo EmotioNL
372
+ This demo allows you to analyse the emotions in a dataset with Dutch sentences.
373
+ _! As we are currently updating this demo, submitting your own data is unavailable for the moment ! However, you can try out the showcase mode 😊_
374
+
375
+ The data should be in tsv-format with two named columns: the first column (id) should contain the sentence IDs, and the second column (text) should contain the actual texts. Optionally, there is a third column named 'date', which specifies the date associated with the text (e.g., tweet date). This column is necessary when the options 'emotion distribution over time' and 'peaks' are selected.
376
+
377
+ You can also try out the demo in showcase mode, which uses example data, namely a dataset with tweets about the COVID-19 pandemic.
378
+ """)
379
+ with gr.Row():
380
+ with gr.Column():
381
+ input_file = gr.File(
382
+ label="Upload a dataset")
383
+ input_checks = gr.CheckboxGroup(
384
+ ["emotion frequencies", "emotion distribution over time", "peaks", "topics"],
385
+ label = "Select options")
386
+ send_btn = gr.Button("Submit data")
387
+ demo_btn = gr.Button("... or showcase with example data")
388
+ with gr.Column():
389
+ message = gr.Textbox(label="Message", visible=False)
390
+
391
+ output_file = gr.File(label="Predictions", visible=False)
392
+ next_button_freq = gr.Button("Show emotion frequencies", visible=False)
393
+
394
+ output_plot = gr.Plot(show_label=False, visible=False).style(container=True)
395
+ next_button_dist = gr.Button("Show emotion distribution over time", visible=False)
396
+
397
+ output_dist = gr.Plot(show_label=False, visible=False)
398
+ next_button_peaks = gr.Button("Show peaks", visible=False)
399
+
400
+ output_peaks = gr.HTML(visible=False)
401
+ next_button_topics = gr.Button("Show topics", visible=False)
402
+
403
+ output_topics = gr.Plot(show_label=False, visible=False)
404
+
405
+ #send_btn.click(fn=file, inputs=[input_file,input_checks], outputs=[output_file,next_button_freq,next_button_dist,next_button_peaks,next_button_topics])
406
+ next_button_freq.click(fn=freq, inputs=[output_file,input_checks], outputs=[output_plot,next_button_dist,next_button_peaks,next_button_topics])
407
+ next_button_dist.click(fn=dist, inputs=[output_file,input_checks], outputs=[output_dist,next_button_peaks,next_button_topics])
408
+ next_button_peaks.click(fn=peaks, inputs=[output_file,input_checks], outputs=[output_peaks,next_button_topics])
409
+ next_button_topics.click(fn=topics, inputs=[output_file,input_checks], outputs=output_topics)
410
+ send_btn.click(fn=unavailable, inputs=[input_file,input_checks], outputs=message)
411
+ demo_btn.click(fn=showcase, inputs=[input_file], outputs=[message,output_file,next_button_freq,next_button_dist,next_button_peaks,next_button_topics])
412
+
413
+
414
+ demo.launch()