import os import datetime import requests from offres_emploi import Api from offres_emploi.utils import dt_to_str_iso from dash import Dash, html, dcc, callback, Output, Input, dash_table, State, _dash_renderer import plotly.express as px import dash_mantine_components as dmc from dash_iconify import DashIconify import pandas as pd from dotenv import load_dotenv _dash_renderer._set_react_version("18.2.0") import plotly.io as pio from flask import Flask # external JavaScript files external_scripts = [ 'https://datacipen-copilotdatast.hf.space/copilot/index.js' ] server = Flask(__name__) # Create a customized version of the plotly_dark theme with a modified background color. custom_plotly_dark_theme = { "layout": { "paper_bgcolor": "#1E1E1E", # Update the paper background color "plot_bgcolor": "#1E1E1E", # Update the plot background color "font": { "color": "#FFFFFF" # Update the font color }, "xaxis": { "gridcolor": "#333333", # Update the x-axis grid color "zerolinecolor": "#666666" # Update the x-axis zero line color }, "yaxis": { "gridcolor": "#333333", # Update the y-axis grid color "zerolinecolor": "#666666" # Update the y-axis zero line color } } } # Apply the customized theme to your Plotly figures pio.templates["custom_plotly_dark"] = custom_plotly_dark_theme pio.templates.default = "custom_plotly_dark" load_dotenv() def localisation(): ListCentroids = [ { "ID": "01", "Longitude": 5.3245259, "Latitude":46.0666003 }, { "ID": "02", "Longitude": 3.5960246, "Latitude": 49.5519632 }, { "ID": "03", "Longitude": 3.065278, "Latitude": 46.4002783 }, { "ID": "04", "Longitude": 6.2237688, "Latitude": 44.1105837 }, { "ID": "05", "Longitude": 6.2018836, "Latitude": 44.6630487 }, { "ID": "06", "Longitude": 7.0755745, "Latitude":43.9463082 }, { "ID": "07", "Longitude": 4.3497308, "Latitude": 44.7626044 }, { "ID": "08", "Longitude": 4.6234893, "Latitude": 49.6473884 }, { "ID": "09", "Longitude": 1.6037147, "Latitude": 42.9696091 }, { "ID": "10", "Longitude": 4.1394954, "Latitude": 48.2963286 }, { "ID": "11", "Longitude": 2.3140163, "Latitude": 43.1111427 }, { "ID": "12", "Longitude": 2.7365234, "Latitude": 44.2786323 }, { "ID": "13", "Longitude": 5.0515492, "Latitude": 43.5539098 }, { "ID": "14", "Longitude": -0.3930779, "Latitude": 49.1024215 }, { "ID": "15", "Longitude": 2.6367657, "Latitude": 44.9643217 }, { "ID": "16", "Longitude": 0.180475, "Latitude": 45.706264 }, { "ID": "17", "Longitude": -0.7082589, "Latitude": 45.7629699 }, { "ID": "18", "Longitude": 2.5292424, "Latitude": 47.0926687 }, { "ID": "19", "Longitude": 1.8841811, "Latitude": 45.3622055 }, { "ID": "2A", "Longitude": 8.9906834, "Latitude": 41.8619761 }, { "ID": "2B", "Longitude": 9.275489, "Latitude": 42.372014 }, { "ID": "21", "Longitude": 4.7870471, "Latitude": 47.4736746 }, { "ID": "22", "Longitude": -2.9227591, "Latitude": 48.408402 }, { "ID": "23", "Longitude": 2.0265508, "Latitude": 46.0837382 }, { "ID": "24", "Longitude": 0.7140145, "Latitude": 45.1489678 }, { "ID": "25", "Longitude": 6.3991355, "Latitude": 47.1879451 }, { "ID": "26", "Longitude": 5.1717552, "Latitude": 44.8055408 }, { "ID": "27", "Longitude": 0.9488116, "Latitude": 49.1460288 }, { "ID": "28", "Longitude": 1.2793491, "Latitude": 48.3330017 }, { "ID": "29", "Longitude": -4.1577074, "Latitude": 48.2869945 }, { "ID": "30", "Longitude": 4.2650329, "Latitude": 43.9636468 }, { "ID": "31", "Longitude": 1.2728958, "Latitude": 43.3671081 }, { "ID": "32", "Longitude": 0.4220039, "Latitude": 43.657141 }, { "ID": "33", "Longitude": -0.5760716, "Latitude": 44.8406068 }, { "ID": "34", "Longitude": 3.4197556, "Latitude": 43.62585 }, { "ID": "35", "Longitude": -1.6443812, "Latitude": 48.1801254 }, { "ID": "36", "Longitude": 1.6509938, "Latitude": 46.7964222 }, { "ID": "37", "Longitude": 0.7085619, "Latitude": 47.2802601 }, { "ID": "38", "Longitude": 5.6230772, "Latitude": 45.259805 }, { "ID": "39", "Longitude": 5.612871, "Latitude": 46.7398138 }, { "ID": "40", "Longitude": -0.8771738, "Latitude": 44.0161251 }, { "ID": "41", "Longitude": 1.3989178, "Latitude": 47.5866519 }, { "ID": "42", "Longitude": 4.2262355, "Latitude": 45.7451186 }, { "ID": "43", "Longitude": 3.8118151, "Latitude": 45.1473029 }, { "ID": "44", "Longitude": -1.7642949, "Latitude": 47.4616509 }, { "ID": "45", "Longitude": 2.2372695, "Latitude": 47.8631395 }, { "ID": "46", "Longitude": 1.5732157, "Latitude": 44.6529284 }, { "ID": "47", "Longitude": 0.4788052, "Latitude": 44.4027215 }, { "ID": "48", "Longitude": 3.4991239, "Latitude": 44.5191573 }, { "ID": "49", "Longitude": -0.5136056, "Latitude": 47.3945201 }, { "ID": "50", "Longitude": -1.3203134, "Latitude": 49.0162072 }, { "ID": "51", "Longitude": 4.2966555, "Latitude": 48.9479636 }, { "ID": "52", "Longitude": 5.1325796, "Latitude": 48.1077196 }, { "ID": "53", "Longitude": -0.7073921, "Latitude": 48.1225795 }, { "ID": "54", "Longitude": 6.144792, "Latitude": 48.7995163 }, { "ID": "55", "Longitude": 5.2888292, "Latitude": 49.0074545 }, { "ID": "56", "Longitude": -2.8746938, "Latitude": 47.9239486 }, { "ID": "57", "Longitude": 6.5610683, "Latitude": 49.0399233 }, { "ID": "58", "Longitude": 3.5544332, "Latitude": 47.1122301 }, { "ID": "59", "Longitude": 3.2466616, "Latitude": 50.4765414 }, { "ID": "60", "Longitude": 2.4161734, "Latitude": 49.3852913 }, { "ID": "61", "Longitude": 0.2248368, "Latitude": 48.5558919 }, { "ID": "62", "Longitude": 2.2555152, "Latitude": 50.4646795 }, { "ID": "63", "Longitude": 3.1322144, "Latitude": 45.7471805 }, { "ID": "64", "Longitude": -0.793633, "Latitude": 43.3390984 }, { "ID": "65", "Longitude": 0.1478724, "Latitude": 43.0526238 }, { "ID": "66", "Longitude": 2.5239855, "Latitude": 42.5825094 }, { "ID": "67", "Longitude": 7.5962225, "Latitude": 48.662515 }, { "ID": "68", "Longitude": 7.2656284, "Latitude": 47.8586205 }, { "ID": "69", "Longitude": 4.6859896, "Latitude": 45.8714754 }, { "ID": "70", "Longitude": 6.1388571, "Latitude": 47.5904191 }, { "ID": "71", "Longitude": 4.6394021, "Latitude": 46.5951234 }, { "ID": "72", "Longitude": 0.1947322, "Latitude": 48.0041421 }, { "ID": "73", "Longitude": 6.4662232, "Latitude": 45.4956055 }, { "ID": "74", "Longitude": 6.3609606, "Latitude": 46.1045902 }, { "ID": "75", "Longitude": 2.3416082, "Latitude": 48.8626759 }, { "ID": "76", "Longitude": 1.025579, "Latitude": 49.6862911 }, { "ID": "77", "Longitude": 2.8977309, "Latitude": 48.5957831 }, { "ID": "78", "Longitude": 1.8080138, "Latitude": 48.7831982 }, { "ID": "79", "Longitude": -0.3159014, "Latitude": 46.5490257 }, { "ID": "80", "Longitude": 2.3380595, "Latitude": 49.9783317 }, { "ID": "81", "Longitude": 2.2072751, "Latitude": 43.8524305 }, { "ID": "82", "Longitude": 1.2649374, "Latitude": 44.1254902 }, { "ID": "83", "Longitude": 6.1486127, "Latitude": 43.5007903 }, { "ID": "84", "Longitude": 5.065418, "Latitude": 44.0001599 }, { "ID": "85", "Longitude": -1.3956692, "Latitude": 46.5929102 }, { "ID": "86", "Longitude": 0.4953679, "Latitude": 46.5719095 }, { "ID": "87", "Longitude": 1.2500647, "Latitude": 45.9018644 }, { "ID": "88", "Longitude": 6.349702, "Latitude": 48.1770451 }, { "ID": "89", "Longitude": 3.5634078, "Latitude": 47.8474664 }, { "ID": "90", "Longitude": 6.9498114, "Latitude": 47.6184394 }, { "ID": "91", "Longitude": 2.2714555, "Latitude": 48.5203114 }, { "ID": "92", "Longitude": 2.2407148, "Latitude": 48.835321 }, { "ID": "93", "Longitude": 2.4811577, "Latitude": 48.9008719 }, { "ID": "94", "Longitude": 2.4549766, "Latitude": 48.7832368 }, { "ID": "95", "Longitude": 2.1802056, "Latitude": 49.076488 }, { "ID": "974", "Longitude": 55.536384, "Latitude": -21.115141 }, { "ID": "973", "Longitude": -53.125782, "Latitude": 3.933889 }, { "ID": "972", "Longitude": -61.024174, "Latitude": 14.641528 }, { "ID": "971", "Longitude": -61.551, "Latitude": 16.265 } ] return ListCentroids def connexion_France_Travail(): client = Api(client_id=os.getenv('POLE_EMPLOI_CLIENT_ID'), client_secret=os.getenv('POLE_EMPLOI_CLIENT_SECRET')) return client def API_France_Travail(romeListArray): client = connexion_France_Travail() todayDate = datetime.datetime.today() month, year = (todayDate.month-1, todayDate.year) if todayDate.month != 1 else (12, todayDate.year-1) start_dt = todayDate.replace(day=1, month=month, year=year) end_dt = datetime.datetime.today() results = [] for k in romeListArray: if k[0:1] == ' ': k = k[1:] params = {"motsCles": k.replace('/', '').replace('-', '').replace(',', '').replace(' ', ','),'minCreationDate': dt_to_str_iso(start_dt),'maxCreationDate': dt_to_str_iso(end_dt),'range':'0-149'} try: search_on_big_data = client.search(params=params) results += search_on_big_data["resultats"] except: print("Il n'y a pas d'offres d'emploi.") results_df = pd.DataFrame(results) return results_df theme_toggle = dmc.Tooltip( dmc.ActionIcon( [ dmc.Paper(DashIconify(icon="radix-icons:sun", width=25), darkHidden=True), dmc.Paper(DashIconify(icon="radix-icons:moon", width=25), lightHidden=True), ], variant="transparent", color="yellow", id="color-scheme-toggle", size="lg", ms="auto", ), label="Changez de thème", position="left", withArrow=True, arrowSize=6, ) styleTitle = { "textAlign": "center", "color": dmc.DEFAULT_THEME["colors"]["orange"][4] } styleToggle = { "marginTop":"25px", "textAlign": "right", } datadefault = [ {"value": "K2105", "label": "K2105"}, {"value": "L1101", "label": "L1101"}, {"value": "L1202", "label": "L1202"}, {"value": "L1507", "label": "L1507"}, {"value": "L1508", "label": "L1508"}, {"value": "L1509", "label": "L1509"}, ] def custom_error_handler(err): # This function defines what we want to happen when an exception occurs # For now, we just print the exception to the terminal with additional text print(f"The app raised the following exception: {err}") app = Dash(__name__, external_scripts=external_scripts, server=server, external_stylesheets=dmc.styles.ALL, on_error=custom_error_handler) app.layout = dmc.MantineProvider( [ html.Div( children=[ dmc.Container( children=[ dmc.Grid( children=[ dmc.GridCol(html.Div( dmc.MultiSelect( label="Selectionnez vos Codes ROME", placeholder="Select vos Codes ROME parmi la liste", id="framework-multi-select", value=['K2105', 'L1101', 'L1202', 'L1507', 'L1508', 'L1509'], data=datadefault, w=600, mb=10, styles={ "input": {"borderColor": dmc.DEFAULT_THEME["colors"]["orange"][2]}, "label": {"color": dmc.DEFAULT_THEME["colors"]["orange"][4]}, }, ) ), span=6), dmc.GridCol(html.Div(dmc.Title(f"Le marché et les statistiques de l'emploi", order=1, size="30", my="20", style=styleTitle)), span=5), dmc.GridCol(html.Div(theme_toggle, style=styleToggle), span=1), dmc.GridCol(html.Div( dcc.Loading( id="loadingRepartition", children=(dcc.Graph(id="figRepartition",selectedData={'points': [{'hovertext': ['01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','2A','2B','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','971','972','973','974']}]})), type="default", ) ), span=6), dmc.GridCol(html.Div( dcc.Loading( id="loadingEmplois", children=(dcc.Graph(id="figEmplois")), type="default", ) ), span=6), dmc.GridCol(html.Div( dcc.Loading( id="loadingContrats", children=(dcc.Graph(id="figContrats")), type="default", ) ), span=6), dmc.GridCol(html.Div( dcc.Loading( id="loadingExperiences", children=(dcc.Graph(id="figExperiences")), type="default", ) ), span=6), dmc.GridCol(html.Div( dcc.Loading( id="loadingCompetences", children=(dcc.Graph(id="figCompetences")), type="default", ) ), span=6), dmc.GridCol(html.Div( dcc.Loading( id="loadingTransversales", children=(dcc.Graph(id="figTransversales")), type="default", ) ), span=6), ], gutter="xs", ) ],size="xxl",fluid=True ), ] ) ], id="mantine-provider", forceColorScheme="dark", theme={ "primaryColor": "indigo", "fontFamily": "'Inter', sans-serif", "components": { "Button": {"defaultProps": {"fw": 400}}, "Alert": {"styles": {"title": {"fontWeight": 500}}}, "AvatarGroup": {"styles": {"truncated": {"fontWeight": 500}}}, "Badge": {"styles": {"root": {"fontWeight": 500}}}, "Progress": {"styles": {"label": {"fontWeight": 500}}}, "RingProgress": {"styles": {"label": {"fontWeight": 500}}}, "CodeHighlightTabs": {"styles": {"file": {"padding": 12}}}, "Table": { "defaultProps": { "highlightOnHover": True, "withTableBorder": True, "verticalSpacing": "sm", "horizontalSpacing": "md", } }, }, # add your colors "colors": { "deepBlue": ["#E9EDFC", "#C1CCF6", "#99ABF0"], # 10 color elements }, "shadows": { # other shadows (xs, sm, lg) will be merged from default theme "md": "1px 1px 3px rgba(0,0,0,.25)", "xl": "5px 5px 3px rgba(0,0,0,.25)", }, "headings": { "fontFamily": "Roboto, sans-serif", "sizes": { "h1": {"fontSize": 30}, }, }, }, ) @callback( Output("mantine-provider", "forceColorScheme"), Input("color-scheme-toggle", "n_clicks"), State("mantine-provider", "forceColorScheme"), prevent_initial_call=True, ) def switch_theme(_, theme): return "dark" if theme == "light" else "light" @callback( Output(component_id='figRepartition', component_property='figure'), Output(component_id='figCompetences', component_property='figure'), Output(component_id='figTransversales', component_property='figure'), Input(component_id='framework-multi-select', component_property='value'), Input("mantine-provider", "forceColorScheme"), ) def create_repartition(array_value, theme): if theme == "dark": template = "plotly_dark" paper_bgcolor = 'rgba(36, 36, 36, 1)' plot_bgcolor = 'rgba(36, 36, 36, 1)' else: template = "ggplot2" paper_bgcolor = 'rgba(255, 255, 255, 1)' plot_bgcolor = 'rgba(255, 255, 255, 1)' df_FT = API_France_Travail(array_value) df = df_FT[['intitule','typeContratLibelle','experienceLibelle','lieuTravail']].copy() df["lieuTravail"] = df["lieuTravail"].apply(lambda x: x['libelle']).apply(lambda x: x[0:3]).apply(lambda x: x.strip()) df.drop(df[df['lieuTravail'] == 'Fra'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'FRA'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Ile'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Mar'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Bou'].index, inplace = True) df.drop(df[df['lieuTravail'] == '976'].index, inplace = True) ######## localisation ######## ListCentroids = localisation() df_localisation = df.groupby('lieuTravail').size().reset_index(name='obs') df_localisation = df_localisation.sort_values(by=['lieuTravail']) df_localisation['longitude'] = df_localisation['lieuTravail'] df_localisation['latitude'] = df_localisation['lieuTravail'] df_localisation["longitude"] = df_localisation['longitude'].apply(lambda x:[loc['Longitude'] for loc in ListCentroids if loc['ID'] == x]).apply(lambda x:''.join(map(str, x))) df_localisation["longitude"] = pd.to_numeric(df_localisation["longitude"], downcast="float") df_localisation["latitude"] = df_localisation['latitude'].apply(lambda x:[loc['Latitude'] for loc in ListCentroids if loc['ID'] == x]).apply(lambda x:''.join(map(str, x))) df_localisation["latitude"] = pd.to_numeric(df_localisation["latitude"], downcast="float") res = requests.get( "https://raw.githubusercontent.com/codeforgermany/click_that_hood/main/public/data/france-regions.geojson" ) fig_localisation = px.scatter_mapbox(df_localisation, lat="latitude", lon="longitude", height=600, template=template, title="La répartition géographique des emplois", hover_name="lieuTravail", size="obs").update_layout( mapbox={ "style": "carto-positron", "center": {"lon": 2, "lat" : 47}, "zoom": 4.5, "layers": [ { "source": res.json(), "type": "line", "color": "green", "line": {"width": 0}, } ], },font=dict(size=10),paper_bgcolor=paper_bgcolor,autosize=True,clickmode='event+select' ) df_FT.dropna(subset=['qualitesProfessionnelles','formations','competences'], inplace=True) df_FT["competences"] = df_FT["competences"].apply(lambda x:[str(e['libelle']) for e in x]).apply(lambda x:'; '.join(map(str, x))) df_FT["qualitesProfessionnelles"] = df_FT["qualitesProfessionnelles"].apply(lambda x:[str(e['libelle']) + ": " + str(e['description']) for e in x]).apply(lambda x:'; '.join(map(str, x))) ######## Compétences professionnelles ######## df_comp = df_FT df_comp['competences'] = df_FT['competences'].str.split(';') df_comp = df_comp.explode('competences') df_comp = df_comp.groupby('competences').size().reset_index(name='obs') df_comp = df_comp.sort_values(by=['obs']) df_comp = df_comp.iloc[-20:] fig_competences = px.bar(df_comp, x='obs', y='competences', orientation='h', color='obs', height=600, template=template, title="Les principales compétences professionnelles", labels={'obs':'nombre'}, color_continuous_scale="Teal", text_auto=True).update_layout(font=dict(size=10),paper_bgcolor=paper_bgcolor,plot_bgcolor=plot_bgcolor,autosize=True).update_traces(hovertemplate=df_comp["competences"] + '
Nombre : %{x}', y=[y[:100] + "..." for y in df_comp['competences']], showlegend=False) ######## Compétences transversales ######## df_transversales = df_FT df_transversales['qualitesProfessionnelles'] = df_FT['qualitesProfessionnelles'].str.split(';') df_comptransversales = df_transversales.explode('qualitesProfessionnelles') df_comptransversales = df_comptransversales.groupby('qualitesProfessionnelles').size().reset_index(name='obs') df_comptransversales = df_comptransversales.sort_values(by=['obs']) df_comptransversales = df_comptransversales.iloc[-20:] fig_transversales = px.bar(df_comptransversales, x='obs', y='qualitesProfessionnelles', orientation='h', color='obs', height=600, template=template, title="Les principales compétences transversales", labels={'obs':'nombre'}, color_continuous_scale="Teal", text_auto=True).update_layout(font=dict(size=10),paper_bgcolor=paper_bgcolor,plot_bgcolor=plot_bgcolor,autosize=True).update_traces(hovertemplate=df_comptransversales["qualitesProfessionnelles"] + '
Nombre : %{x}', y=[y[:80] + "..." for y in df_comptransversales["qualitesProfessionnelles"]], showlegend=False) return fig_localisation, fig_competences, fig_transversales def create_emploi(df, theme): if theme == "dark": template = "plotly_dark" paper_bgcolor = 'rgba(36, 36, 36, 1)' plot_bgcolor = 'rgba(36, 36, 36, 1)' else: template = "ggplot2" paper_bgcolor = 'rgba(255, 255, 255, 1)' plot_bgcolor = 'rgba(255, 255, 255, 1)' ######## Emplois ######## df_intitule = df.groupby('intitule').size().reset_index(name='obs') df_intitule = df_intitule.sort_values(by=['obs']) df_intitule = df_intitule.iloc[-25:] fig_intitule = px.bar(df_intitule, x='obs', y='intitule', height=600, orientation='h', color='obs', template=template, title="Les principaux emplois", labels={'obs':'nombre'}, color_continuous_scale="Teal", text_auto=True).update_layout(font=dict(size=10),paper_bgcolor=paper_bgcolor,plot_bgcolor=plot_bgcolor, autosize=True).update_traces(hovertemplate=df_intitule["intitule"] + '
Nombre : %{x}', y=[y[:100] + "..." for y in df_intitule["intitule"]], showlegend=False) return fig_intitule def create_contrat(df, theme): if theme == "dark": template = "plotly_dark" paper_bgcolor = 'rgba(36, 36, 36, 1)' else: template = "ggplot2" paper_bgcolor = 'rgba(255, 255, 255, 1)' ######## Types de contrat ######## df_contrat = df.groupby('typeContratLibelle').size().reset_index(name='obs') fig_contrat = px.pie(df_contrat, names='typeContratLibelle', values='obs', color='obs', height=600, template=template, title="Les types de contrat", labels={'obs':'nombre'}, color_discrete_sequence=px.colors.qualitative.Safe).update_traces(textposition='inside', textinfo='percent+label').update_layout(font=dict(size=10),paper_bgcolor=paper_bgcolor) return fig_contrat def create_experience(df, theme): if theme == "dark": template = "plotly_dark" paper_bgcolor = 'rgba(36, 36, 36, 1)' else: template = "ggplot2" paper_bgcolor = 'rgba(255, 255, 255, 1)' ######## Expériences professionnelles ######## df_experience = df.groupby('experienceLibelle').size().reset_index(name='obs') fig_experience = px.pie(df_experience, names='experienceLibelle', values='obs', color='obs', height=600, template=template, title="Les expériences professionnelles", labels={'obs':'nombre'}, color_discrete_sequence=px.colors.qualitative.Safe).update_traces(textposition='inside', textinfo='percent+label').update_layout(font=dict(size=10),paper_bgcolor=paper_bgcolor) return fig_experience @callback( Output(component_id='figEmplois', component_property='figure'), Input('figRepartition', 'selectedData'), Input(component_id='framework-multi-select', component_property='value'), Input("mantine-provider", "forceColorScheme"), ) def update_emploi(selectedData, array_value, theme): options = [] if selectedData != None: if type(selectedData['points'][0]['hovertext']) == str: options.append(selectedData['points'][0]['hovertext']) else: options = selectedData['points'][0]['hovertext'] else: options = ['01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','2A','2B','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','971','972','973','974'] df_FT = API_France_Travail(array_value) df = df_FT[['intitule','typeContratLibelle','experienceLibelle','lieuTravail']].copy() df["lieuTravail"] = df["lieuTravail"].apply(lambda x: x['libelle']).apply(lambda x: x[0:3]).apply(lambda x: x.strip()) df.drop(df[df['lieuTravail'] == 'Fra'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'FRA'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Ile'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Mar'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Bou'].index, inplace = True) df.drop(df[df['lieuTravail'] == '976'].index, inplace = True) df = df[df['lieuTravail'].isin(options)] return create_emploi(df, theme) @callback( Output(component_id='figContrats', component_property='figure'), Input('figRepartition', 'selectedData'), Input(component_id='framework-multi-select', component_property='value'), Input("mantine-provider", "forceColorScheme"), ) def update_contrat(selectedData, array_value, theme): options = [] if selectedData != None: if type(selectedData['points'][0]['hovertext']) == str: options.append(selectedData['points'][0]['hovertext']) else: options = selectedData['points'][0]['hovertext'] else: options = ['01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','2A','2B','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','971','972','973','974'] df_FT = API_France_Travail(array_value) df = df_FT[['intitule','typeContratLibelle','experienceLibelle','lieuTravail']].copy() df["lieuTravail"] = df["lieuTravail"].apply(lambda x: x['libelle']).apply(lambda x: x[0:3]).apply(lambda x: x.strip()) df.drop(df[df['lieuTravail'] == 'Fra'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'FRA'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Ile'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Mar'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Bou'].index, inplace = True) df.drop(df[df['lieuTravail'] == '976'].index, inplace = True) df = df[df['lieuTravail'].isin(options)] return create_contrat(df, theme) @callback( Output(component_id='figExperiences', component_property='figure'), Input('figRepartition', 'selectedData'), Input(component_id='framework-multi-select', component_property='value'), Input("mantine-provider", "forceColorScheme"), ) def update_experience(selectedData, array_value, theme): options = [] if selectedData != None: if type(selectedData['points'][0]['hovertext']) == str: options.append(selectedData['points'][0]['hovertext']) else: options = selectedData['points'][0]['hovertext'] else: options = ['01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','2A','2B','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','971','972','973','974'] df_FT = API_France_Travail(array_value) df = df_FT[['intitule','typeContratLibelle','experienceLibelle','lieuTravail']].copy() df["lieuTravail"] = df["lieuTravail"].apply(lambda x: x['libelle']).apply(lambda x: x[0:3]).apply(lambda x: x.strip()) df.drop(df[df['lieuTravail'] == 'Fra'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'FRA'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Ile'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Mar'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Bou'].index, inplace = True) df.drop(df[df['lieuTravail'] == '976'].index, inplace = True) df = df[df['lieuTravail'].isin(options)] return create_experience(df, theme) if __name__ == '__main__': app.run_server(debug=True)