How to display/put/use LDA model in my dash app - python

I would like to display/use/put my LDA model in my dash app. Here's the code for the LDA model which works and that I've saved in html on my computer :
# Libraries
import spacy
from gensim.corpora import Dictionary
from gensim.models import LdaModel
import pyLDAvis.gensim_models
import pandas as pd
nlp_teletravail = spacy.load("fr_core_news_sm")
# Create df for the example
data = [['tweet content in french'], ['tweet 2 content in french'], ['tweet 3 content in french']] # lots of tweets and other columns but not useful for the example
# Create the pandas DataFrame
df = pd.DataFrame(data, columns=['Preprocessed_tweets'])
spacy_docs_teletravail = list(nlp_teletravail.pipe(df["Preprocessed_tweets"]))
# Create empty list called docs_teletravail
docs_teletravail = []
# Pre processing
# For each document in spacy_docs_teletravail
for doc in spacy_docs_teletravail:
# We create empty list called tokens_teletravail
tokens_teletravail = []
# for each token in each document of spacy_docs_teletravail
for token in doc:
# pre processing 1 and 2
if len(token.orth_) > 2 and not token.is_stop:
# pre processing 3 and 4
tokens_teletravail.append( token.lemma_.lower() )
# append results of tokens_teletravail in docs_teletravail
docs_teletravail.append( tokens_teletravail )
dictionary_teletravail = Dictionary(docs_teletravail)
corpus_teletravail = [ dictionary_teletravail.doc2bow(doc) for doc in docs_teletravail]
model_teletravail_passes_5 = LdaModel(corpus=corpus_teletravail,
id2word=dictionary_teletravail,
num_topics=10,
chunksize=1000,
passes=5,
random_state=1)
vis_data_teletravail = pyLDAvis.gensim_models.prepare(model_teletravail_passes_5, corpus_teletravail, dictionary_teletravail, sort_topics=False)
# Export the graph and store it where we want in our computer
pyLDAvis.save_html(vis_data_teletravail, 'C:/Users/mario/Downloads/lda_model_passes_5.html')
Maybe you can add content for the tweets (random sentences that you can find on the internet). I think I can't load my html file on the post but don't hesitate to tell me if it's possible and I'll do it so that you don't have to run the first part. And here's the code of my dash app where I have multiple tabs and subtabs but I don't put their content here because it's useless, you just have the code with the tabs (empty). I would like to put the LDA model in tab 3 (Latent Dirichlet Allocation Model) subtab 10 (LDA Model 10 topics). I left most of my attempts in comments to return the LDA model in subtab10 but nothing is happening (no errors, nothing appearing on the dash app). Thank you for your help !
# Needed libraries
#import pandas as pd
import dash
import dash_bootstrap_components as dbc
#import plotly.express as px
#import numpy as np
from dash import dcc, html
from dash.dependencies import Input, Output
from dash_bootstrap_templates import ThemeSwitchAIO, template_from_url
# Two different templates stored in variables for the dash app
template_theme1 = "cyborg"
template_theme2 = "lumen"
url_theme1 = dbc.themes.CYBORG
url_theme2 = dbc.themes.LUMEN
# Link which gives access to the templates
dbc_css = (
"https://cdn.jsdelivr.net/gh/AnnMarieW/dash-bootstrap-templates#V1.0.1/dbc.min.css"
)
# Create the app and define the main theme in external_stylesheets
app = dash.Dash(__name__, external_stylesheets=[url_theme1, dbc_css])
# Define a sentence that appears on the top left of the app in order to choose between the two proposed themes
header = html.P("Click if you want to change theme of graphics",style={'textAlign': 'left','font-size':'300','font-family':'helvetica'})
# Create the layout of the app
app.layout = html.Div([ # html Div to use html components (style, text, tabs, subtabs etc)
html.H1('Health consequences during covid-19 pandemic dashboard', style={'textAlign': 'center','font-size':'300','font-family':'helvetica'}),
dbc.Container( # dbc container and row to use dbc Col to define the different themes to choose
dbc.Row(
[
dbc.Col( # Define the two possible themes to choose
[
header, # header is the sentence that we've dehttps://stackoverflow.com/questions/64736956/how-to-use-iframe-in-dash-plotly-python-htmlfined earlier in header variable
ThemeSwitchAIO( # switch with icons
aio_id="theme", # id of the switch
themes=[url_theme1,url_theme2], # proposed themes that we've defined earlier
),
])])),
dcc.Tabs(id='tabs', value='Tab1', style={'background-color': 'black'}, children=[
# Create tabs and their sub tabs
dcc.Tab(label='Data information', id='tab1', value='Tab1', style={'textAlign': 'center', 'font-size':'100','font-family':'helvetica', 'background-color': 'black'},children =[ # First tab
dcc.Tabs(id="subtabs1", value='Subtab1',children=[ # Create sub tabs in the first tab
dcc.Tab(label='Basic information about the dashboard', id='subtab1', value='Subtab1',style={'textAlign': 'center','font-size':'100','font-family':'helvetica', 'background-color': 'black'}), # First sub tab of tab 1
dcc.Tab(label='Number of collected tweets', id='subtab2', value='Subtab2',style={'textAlign': 'center', 'font-size':'100','font-family':'helvetica', 'background-color': 'black'}), # Second sub tab of tab 1
dcc.Tab(label='Number of collected tweets per month each year', id='subtab3', value='Subtab3',style={'textAlign': 'center', 'font-size':'100','font-family':'helvetica', 'background-color': 'black'}), # Third sub tab of tab 1
dcc.Tab(label='Wordcloud', id='subtab4', value='Subtab4',style={'textAlign': 'center', 'font-size':'100','font-family':'helvetica', 'background-color': 'black'})]) # Fourth sub tab of tab 1
]),
dcc.Tab(label='Sentiment Analysis', id='tab2', value='Tab2',style={'textAlign': 'center','font-size':'100','font-family':'helvetica', 'background-color': 'black'}, children=[ # Create the Second tab
dcc.Tabs(id="subtabs2", value='Subtab2', children=[ # Create sub tabs for the second tab
dcc.Tab(label='Number or percentage of tweets according to sentiments', id='subtab5', value='Subtab5', style={'textAlign': 'center','font-size':'100','font-family':'helvetica', 'background-color': 'black'}), # First sub tab of tab 2
dcc.Tab(label='Percentage of tweets according to sentiments and time slots', id='subtab6', value='Subtab6', style={'textAlign': 'center','font-size':'100','font-family':'helvetica', 'background-color': 'black'}), # Second sub tab of tab 2
dcc.Tab(label='Number or percentage of tweets according to sentiments and time slots', id='subtab7', value='Subtab7', style={'textAlign': 'center','font-size':'100','font-family':'helvetica', 'background-color': 'black'}), # Third sub tab of tab 2
dcc.Tab(label='Number or percentage of tweets according to sentiments each year', id='subtab8', value='Subtab8', style={'textAlign': 'center','font-size':'100','font-family':'helvetica', 'background-color': 'black'})]) # Fourth sub tab of tab 2
]),
dcc.Tab(label='Latent Dirichlet Allocation Model', id='tab3', value='Tab3',style={'textAlign': 'center','font-size':'100','font-family':'helvetica', 'background-color': 'black'}, children=[ # Create the Third tab
dcc.Tabs(id="subtabs3", value='Subtab3', children=[
dcc.Tab(label='LDA Model interpretation', id='subtab9', value='Subtab9', style={'textAlign': 'center','font-size':'100','font-family':'helvetica', 'background-color': 'black'}), # First sub tab of tab 3
dcc.Tab(label='LDA Model 10 topics', id='subtab10', value='Subtab10', style={'textAlign': 'center','font-size':'100','font-family':'helvetica', 'background-color': 'black'}), # Second sub tab of tab 3
dcc.Tab(label='LDA Model 5 topics', id='subtab11', value='Subtab11', style={'textAlign': 'center','font-size':'100','font-family':'helvetica', 'background-color': 'black'})]) # Third sub tab of tab 3
]),
dcc.Tab(label='Network Graph', id='tab4', value='Tab4',style={'textAlign': 'center','font-size':'100','font-family':'helvetica', 'background-color': 'black'}, children=[ # Create the fourth tab
dcc.Tabs(id="subtabs4", value='Subtab4', children=[
dcc.Tab(label='To determine', id='subtab13', value='Subtab13', style={'textAlign': 'center','font-size':'100','font-family':'helvetica', 'background-color': 'black'}), # First sub tab of tab 4
dcc.Tab(label='To determine', id='subtab14', value='Subtab14', style={'textAlign': 'center','font-size':'100','font-family':'helvetica', 'background-color': 'black'}), # Second sub tab of tab 4
dcc.Tab(label='To determine', id='subtab15', value='Subtab15', style={'textAlign': 'center','font-size':'100','font-family':'helvetica', 'background-color': 'black'})]) # Third sub tab of tab 4
])
])
])
############################################ Tab 3 LDA MODEL
############### Sub tab 10 LDA Model 10 topics
# Callback for Tab 3 and subtab 10 LDA Model 10 topics
#app.callback(Output('subtab10', 'children'), # Output
[Input('subtabs3', 'value'), # Input
Input(ThemeSwitchAIO.ids.switch("theme"),"value")]) # Another input is the selected theme/template
# Create function to display lda model
def display_lda_subtab10(value,toggle): # 2 parameters value for which subtab and toggle for theme/template
if value == 'Subtab10':# If we are in subtab2 in tab 1 we return a graph
template = template_theme1 if toggle else template_theme2 # We define the theme selected
#lda_10_topics = html.Iframe(src='C:/Users/mario/Desktop/M2 Health Data Science 2022 2023/Mémoire/Projet Pro M2 2022 2023/Codes_tests_apres_rapport_detape/LDA/lda_model_topics_10.html')
#return html.Div([dcc.Graph(figure=lda_10_topics)])
# https://stackoverflow.com/questions/64736956/how-to-use-iframe-in-dash-plotly-python-html
#return html.Div([dcc.Graph(id='example'),
# html.Iframe(src='C:/Users/mario/Desktop/M2 Health Data Science 2022 2023/Mémoire/Projet Pro M2 2022 2023/Codes_tests_apres_rapport_detape/LDA/lda_model_topics_10.html')
# ])
#return html.Div([dcc.Graph(id='example'),
# html.Iframe(src=r'C:/Users/mario/Desktop/M2 Health Data Science 2022 2023/Mémoire/Projet Pro M2 2022 2023/Codes_tests_apres_rapport_detape/LDA/lda_model_topics_10.html')
# ])
#https://stackoverflow.com/questions/68269257/local-html-file-wont-load-properly-into-dash-application
#return html.Div([html.Iframe(src="assets/lda_model_topics_10.html")])
# https://stackoverflow.com/questions/74534261/dash-include-custom-html-object
#lda_10_topics = html.Iframe(src=r'C:/Users/mario/Desktop/M2 Health Data Science 2022 2023/Mémoire/Projet Pro M2 2022 2023/Codes_tests_apres_rapport_detape/LDA/lda_model_topics_10.html')
#with open("C:/Users/mario/Downloads/lda_model_passes_5_json.json",'r') as f:
#with open(lda_passes_5_json,'r') as f:
# return html.Div([dcc.Graph(figure=json.load(f))])
#return json.load(f)
#html.Iframe(src=r'static/lda_model_topics_10.html')
#html.Div([html.Iframe(src=r'C:/Users/mario/Desktop/M2 Health Data Science 2022 2023/Mémoire/Projet Pro M2 2022 2023/Codes_tests_apres_rapport_detape/LDA/lda_model_topics_10.html')])
# Run the dash app
if __name__ =='__main__':
app.run_server(debug=False)

I found the solution by creating a folder called assets on my computer. Then we put the lda.html file inside. After that you can add the following code in the function and it works (your python path should be the one where the folder 'assets" is) !
return html.Div([html.Iframe(src="assets/lda_model_topics_10.html")])
You might have to adjust height and width after : src="...", height=..., width=...

Related

How to trigger call back function in dash_pivottable

I am trying to define a callback function that is called when a cell of my pivot table is called.
My code is below.
Unfortunately test_function test function is only called once and not each time a cell is clicked as i want.
Is this possible and what changes do i need to make to achieve this?
import jupyter_dash as dash
from dash import html, Input, Output, State
import dash_pivottable
app = dash.JupyterDash(__name__)
server = app.server
app.layout = html.Div(
[dash_pivottable.PivotTable(
id='table',
data=[
['Animal', 'Count', 'Location'],
['Zebra', 5, 'SF Zoo'],
['Tiger', 3, 'SF Zoo'],
['Zebra', 2, 'LA Zoo'],
['Tiger', 4, 'LA Zoo'],
],
cols=["Animal"],
rows=["Location"],
vals=["Count"],
),
html.Div(id='click-data', style={'whiteSpace': 'pre-wrap'})]
)
#app.callback(
Output('click-data', component_property="children"),
[Input('table','clickData'),
Input("table", "hoverData"),
Input("table", component_property="cols"),
Input("table", component_property="rows"),
Input("table", component_property="rowOrder"),
Input("table", component_property="colOrder"),
Input("table", component_property="aggregatorName"),
Input("table", component_property="rendererName")]
)
def test_function(clickData, hoverData, cols, rows, row_order, col_order, aggregator, renderer):
print("hello")
print(rows)
print(cols)
print(hoverData)
return clickData
if __name__ == "__main__":
app.run_server(mode='inline')

Plotly Choropleth Map Not Showing Up

I'm trying to display a Plotly Choropleth Map in Jupyter Notebooks (I'm a beginner with this type of stuff) and for some reason it won't display correctly.
The csv file I am using for it can be found here:
https://www.kaggle.com/ajaypalsinghlo/world-happiness-report-2021
Here is the code leading up to the choropleth:
# here we're assigning the hover data columns to use for our choropleth map below
hover_data_cols_df = ['Country', 'Life Ladder', 'Log GDP per capita', 'Social support', 'Healthy life expectancy at birth', 'Freedom to make life choices', 'Generosity', 'Perceptions of corruption']
df.groupby('Year').Country.count()
and here is the code for the actual choropleth:
choropleth_map = px.choropleth(df,
locations="Country",
color='Life Ladder',
hover_name = 'Life Ladder',
hover_data = hover_data_cols_df,
color_continuous_scale = px.colors.sequential.Oranges,
animation_frame="Year"
).update_layout (title_text = 'World Happiness Index - year wise data', title_x = 0.5,);
iplot(choropleth_map)
I'm not getting any error messages attached to it currently, however when I check my console log on my browser, I do find this error:
Wolrd-Happiness-Report.ipynb:1 Uncaught ReferenceError: require is not defined
at <anonymous>:1:17
at t.attachWidget (jlab_core.64abc115a1efeec58694.js?v=64abc115a1efeec58694:2)
at t.insertWidget (jlab_core.64abc115a1efeec58694.js?v=64abc115a1efeec58694:2)
at x._insertOutput (jlab_core.64abc115a1efeec58694.js?v=64abc115a1efeec58694:2)
at x.onModelChanged (jlab_core.64abc115a1efeec58694.js?v=64abc115a1efeec58694:2)
at m (jlab_core.64abc115a1efeec58694.js?v=64abc115a1efeec58694:2)
at Object.l [as emit] (jlab_core.64abc115a1efeec58694.js?v=64abc115a1efeec58694:2)
at e.emit (jlab_core.64abc115a1efeec58694.js?v=64abc115a1efeec58694:2)
at c._onListChanged (jlab_core.64abc115a1efeec58694.js?v=64abc115a1efeec58694:2)
at m (jlab_core.64abc115a1efeec58694.js?v=64abc115a1efeec58694:2)
I'm not too sure if this is related or not!
Thanks all!
Your task requires a setting that associates a country name with a country on the map. It requires that the location mode be the country name.
import pandas as pd
df = pd.read_csv('./data/world-happiness-report.csv', sep=',')
df.sort_values('year', ascending=True, inplace=True)
hover_data_cols_df = ['Country name', 'year', 'Life Ladder', 'Log GDP per capita', 'Social support', 'Healthy life expectancy at birth', 'Freedom to make life choices', 'Generosity', 'Perceptions of corruption']
import plotly.express as px
fig = px.choropleth(df,
locations="Country name",
locationmode='country names',
color='Life Ladder',
hover_name = 'Life Ladder',
hover_data = hover_data_cols_df,
color_continuous_scale = px.colors.sequential.Oranges,
animation_frame="year"
)
fig.update_layout (title_text = 'World Happiness Index - year wise data', title_x = 0.5,);
fig.show()

Build interactive dashboard using dash python

so i am trying to make a interactive dashboard using dash plotly in python using below data as example:
Date Traded Qty Deliverable Qty Delivery % LTP Open Interest
0 2020-12-18 29816205 5872798 19.70 268.15 73110000
1 2020-12-21 55160758 14528986 26.34 272.00 71454000
2 2020-12-22 51189571 10781372 21.06 253.85 71013000
3 2020-12-23 29056404 4792004 16.49 258.20 67350000
4 2020-12-24 28585509 6820426 23.86 263.75 68697000
It is saved as pandas dataframe and want to it be similar to below image:
Sorry for my shitty drawing.
In chart I want "Delivery %" to be show when hover over "Deliverable Qty"
I have no experience with Dash, but this page will help you do it. I suggest you look into it and try to write some code before asking questions. I'm in a jupyterlab environment, so I've implemented some live riley for it.
import dash
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import io
import pandas as pd
data = '''
Date "Traded Qty" "Deliverable Qty" "Delivery %" LTP "Open Interest"
0 2020-12-18 29816205 5872798 19.70 268.15 73110000
1 2020-12-21 55160758 14528986 26.34 272.00 71454000
2 2020-12-22 51189571 10781372 21.06 253.85 71013000
3 2020-12-23 29056404 4792004 16.49 258.20 67350000
4 2020-12-24 28585509 6820426 23.86 263.75 68697000
'''
df = pd.read_csv(io.StringIO(data), delim_whitespace=True)
fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_trace(go.Bar(x=df['Date'], y=df['Traded Qty'], name='Traded Qty'))
fig.add_trace(go.Bar(x=df['Date'],
y=df['Deliverable Qty'],
name='Deliverable Qty',
hovertext=df['Delivery %'],
hovertemplate='<br>'.join([
'Deliverable Qty: %{y}',
'Delivery %: %{hovertext}'
])
))
fig.add_trace(go.Scatter(x=df['Date'], y=df['LTP'], mode='lines+markers', name='LTP'), secondary_y=True)
fig.add_trace(go.Scatter(x=df['Date'], y=df['Open Interest'], mode='lines+markers', name='Open Interest'))
fig.update_layout(xaxis=dict(type = "category"), barmode='stack', margin=dict(l=20, r=20, t=20, b=20))
fig.update_yaxes(range=[0,300], secondary_y=True)
# instance create
app = JupyterDash(__name__)
# app = dash.Dash(__name__)
app.layout = html.Div(children=[
html.H3(children='Trade Chart'),
dcc.Graph(
id='example-graph',
figure=fig
)
])
if __name__ == '__main__':
# notebook on action
app.run_server(mode='inline')
# app.run_server(debug=True)

plotly-dash : Autocomplete address in dropdown / text field using either google places / mapbox api

I have an address field and a dropdown where I intend to populate the autocomplete suggestions from mapbox API. In the callback, I pass the query string from input id='address_autocomplete'. However, I am not seeing the values returned by the function population dropdown.
dbc.InputGroup(
[
dbc.InputGroupAddon("Property Address"),
dcc.Input(id='address_autocomplete'),
dcc.Dropdown(id='address_dropdown',style={'width':'60%'})
],
style={'margin-top':'30px', 'width': '53%', 'float': 'left'},
),
# Property address autocomplete
#app.callback(Output('address_dropdown', 'options'),
[Input('address_autocomplete', 'value')])
def autocomplete_address(value):
print(value)
addr = {}
# Call mapbox API and limit Autocomplete address suggestions
ret_obj = geocoder.forward(value, lon=-112.0913905, lat=33.4514652, limit=3)
response = ret_obj.json()
for i in range(len(response['features'])):
addr["res{}".format(i)] = response['features'][i]['place_name']
if value:
return [{'label': addr['res_0'], 'value': addr['res_0']},
{'label': addr['res_1'], 'value': addr['res_1']},
{'label': addr['res_2'], 'value': addr['res_2']}]
# Function call
r = geocoder.forward('Washington Park', lon=-112.0913905, lat=33.4514652, limit=3)
rj = r.json()
# Return
Washington Park, Phoenix, Arizona 85015, United States
Washington Park Playground, Phoenix, Arizona 85015, United States
Washington Park, Chicago, Illinois 60637, United States
check out this minimal example of what I believe you're trying to accomplish: Show a drop down list of city/state suggestions as the user types-
index_layout = html.Div([
dbc.Input(
type="text",
id=dict(type='searchData', id='dest-loc'),
placeholder="Enter Location",
persistence=False,
autocomplete="off",
list='list-suggested-inputs'
),
html.Datalist(id='list-suggested-inputs', children=[html.Option(value='empty')])
]
)
#app.callback(
Output('list-suggested-inputs', 'children'),
Input({"id": 'dest-loc', "type": "searchData"}, "value"),
prevent_initial_call=True
)
def suggest_locs(value):
if len(value) < 4:
raise dash.exceptions.PreventUpdate
google_api_key ='YOUR KEY'
url = f'https://maps.googleapis.com/maps/api/place/autocomplete/json?input={value}&types=locality&region=us&key={google_api_key}'
r = requests.get(url)
print(r.json()['predictions'][0])
return [html.Option(value=l['description']) for l in r.json()['predictions']]
key notes:
add Datalist html component
in the Input, set list = id of your Datalist element
parameter types=locality in google api call

How to select only label from a dict for graph title (Plotly Dash)

I have a dictionary with labels and key as shown below.
country = pd.read_csv('assets/countries.csv')
country = country.set_index('Code')
country_options = [{'label': f'({cod}) {country.loc[cod, "Country"]} ',
'value': f'{cod}'} for cod in country.index]
[{'label': '(AFG) Afghanistan ', 'value': 'AFG'}, {'label': '(ALB) Albania ', 'value': 'ALB'}, {'label': '(DZA) Algeria '.....
I also have a callback to update a graph and would like to add the title depending on the option selected from a dropdown list.
def update_graph(indi=indicator_options,coun=country_options):
df = indicator_select(coun, indi)
graph_content = dict(data=line_plot(df),
layout=go.Layout(
title=coun,
yaxis=dict(hoverformat='.1f'),
)
)
return graph_content
However, the title=coun will return me the 3 letter symbol (value) of the dict, but I need the label with the symbol and the name. Is it possible?
The value prop of the dropdown will only ever return the value part of the options dictionary, and not the label part. What you could do is create a mapping for the values you need, like this:
country_labels = [{f'{cod}': f'({cod}) {country.loc[cod, "Country"]}'} for cod in country.index]
And then just do title=country_labels[coun],

Categories