CSS not working in dash/plotly express

Hello ! i have a problem with my css, i created a python code, created a folder “assets” and put the file “style.css” inside, but when i try, for exemple, to make the h1 green, it dont works.

import dash
from dash import dcc, html
import pandas as pd
import plotly.express as px
from dash.dependencies import Input, Output
import plotly.io as pio

# Charger les données depuis le fichier CSV
df = pd.read_csv(r'C:\Users\Roche\Desktop\BrawlAPI\battlelogs csv\battlelog final.csv')

# Dictionnaire des cartes associées à chaque mode de jeu
mode_to_maps = {
    "Gem Grab": [
        "Hard Rock Mine", "Gem Fort", "Undermine", "Double Swoosh",
        "Minecart Madness", "Acute Angle", "Rustic Arcade", "Open Space",
        "Last Stop", "Sneaky Sneak", "Ahead Of The Curve", "Bear Trap"
    ],
    "Heist": [
        "Kaboom Canyon", "Safe Zone", "Hot Potato", "Bridge Too Far",
        "Diamond Dome", "Secret Or Mystery"
    ],
    "Hot Zone": [
        "Open Business", "Parallels Plays", "Ring of Fire",
        "Dueling Beetles", "Local Businesses", "Misty Meadows"
    ],
    "Bounty": [
        "Snake Prairie", "Shooting Star", "Hideout", "Canal Grande",
        "Flank Attack", "Crowd Strike"
    ],
    "Knockout": [
        "Goldarm Gulch", "Belles Rock", "Deep End", "Flaring Phoenix",
        "Out In The Open", "News Horizons", "Between The Rivers",
        "Four Levels", "Twilight Passage", "Hard Lane",
        "Island Hooping", "Sunset Spar"
    ],
    "Brawl Ball": [
        "Backyard Bowl", "Triple Dribble", "Sneaky Fields",
        "Super Beach", "Pinball Dreams", "Center Stage", "Beach Ball",
        "Sunny Soccer", "Penalty Kick", "Retina", "Offside Trap",
        "Back Pocket"
    ]
}

# Créer une colonne pour le mode de jeu en fonction de la carte
def get_mode_from_map(map_name):
    for mode, maps in mode_to_maps.items():
        if map_name in maps:
            return mode
    return None

# Ajouter une colonne 'mode' au DataFrame
df['mode'] = df['map'].apply(get_mode_from_map)

# Extraire tous les joueurs uniques des colonnes P1 à P6
all_players = pd.concat([df['P1'], df['P2'], df['P3'], df['P4'], df['P5'], df['P6']]).dropna().unique()

# Créer l'application Dash
#assets_path = r"C:\Users\Roche\Desktop\BrawlAPI\Interface\assets"
app = dash.Dash(__name__)
# Mise en page de l'application
app.layout = html.Div([
    
    html.H1("Statistiques Brawl Stars"),
    # Menu déroulant pour sélectionner un joueur
    html.Label("Sélectionner un joueur"),
    dcc.Dropdown(
        id='player-dropdown',
        options=[{'label': player, 'value': player} for player in all_players],
        value=all_players[0],
        clearable=False
    ),

    # Menu déroulant pour sélectionner le mode de jeu
    html.Label("Sélectionner le mode de jeu"),
    dcc.Dropdown(
        id='mode-dropdown',
        options=[{'label': mode, 'value': mode} for mode in mode_to_maps.keys()],
        value=list(mode_to_maps.keys())[0],
        clearable=False
    ),

    # Menu déroulant pour sélectionner une carte (mis à jour en fonction du mode sélectionné)
    html.Label("Sélectionner la carte"),
    dcc.Dropdown(
        id='map-dropdown',
        clearable=False
    ),
# Graphique des taux de victoire par mode de jeu
    dcc.Graph(id='victory-by-mode-graph'),
    # Graphique des meilleurs choix de l'équipe
    dcc.Graph(id='best-picks-team-graph'),
    # Graphique des meilleurs choix contre l'équipe
    dcc.Graph(id='best-picks-against-graph')
])

# Callback pour mettre à jour les cartes en fonction du mode sélectionné
@app.callback(
    Output('map-dropdown', 'options'),
    [Input('mode-dropdown', 'value')]
)
def update_map_dropdown(selected_mode):
    # Retourner les cartes correspondant au mode sélectionné
    maps = mode_to_maps.get(selected_mode, [])
    return [{'label': map_name, 'value': map_name} for map_name in maps]

# Callback pour mettre à jour le graphique des taux de victoire par mode de jeu
@app.callback(
    Output('victory-by-mode-graph', 'figure'),
    [Input('player-dropdown', 'value')]
)
def update_victory_by_mode_graph(selected_player):
    # Filtrer les données pour le joueur sélectionné
    player_filter = (
        (df['P1'] == selected_player) |
        (df['P2'] == selected_player) |
        (df['P3'] == selected_player) |
        (df['P4'] == selected_player) |
        (df['P5'] == selected_player) |
        (df['P6'] == selected_player)
    )
    filtered_data = df[player_filter]

    if filtered_data.empty:
        return px.bar(title="Aucune donnée disponible")

    # Calculer le taux de victoire par mode de jeu
    victory_data = filtered_data.dropna(subset=['team1 result', 'mode'])
    total_matches = victory_data['mode'].value_counts().reset_index()
    total_matches.columns = ['mode', 'Total Matches']

    victory_counts = victory_data[victory_data['team1 result'] == 'victory']['mode'].value_counts().reset_index()
    victory_counts.columns = ['mode', 'Victory Count']

    merged_df = pd.merge(total_matches, victory_counts, on='mode', how='left')
    merged_df['Victory Count'] = merged_df['Victory Count'].fillna(0)
    merged_df['Victory Rate (%)'] = (merged_df['Victory Count'] / merged_df['Total Matches']) * 100
    pio.templates.default = None
    fig = px.bar(merged_df, x='mode', y='Victory Rate (%)', color='mode', title='Taux de victoire par mode de jeu (%)')
    return fig

# Updated callback for the "best-picks-team-graph"
@app.callback(
    Output('best-picks-team-graph', 'figure'),
    [Input('player-dropdown', 'value'),
     Input('map-dropdown', 'value')]
)
def update_best_picks_team_graph(selected_player, selected_map):
    # Filter the data to get the rows where the selected player is in one of the P columns
    player_filter = (
        (df['P1'] == selected_player) |
        (df['P2'] == selected_player) |
        (df['P3'] == selected_player) |
        (df['P4'] == selected_player) |
        (df['P5'] == selected_player) |
        (df['P6'] == selected_player)
    )
    filtered_data = df[player_filter]

    # If no data is found, return an empty figure
    if filtered_data.empty:
        empty_fig = px.bar(title="Aucune donnée disponible")
        return empty_fig

    # Filter data by the selected map
    map_filtered_data = filtered_data[filtered_data['map'] == selected_map]

    # Determine which Brawler column to use based on the player's position
    if (map_filtered_data['P1'] == selected_player).any():
        brawler_column = 'brawler1'
    elif (map_filtered_data['P2'] == selected_player).any():
        brawler_column = 'brawler2'
    elif (map_filtered_data['P3'] == selected_player).any():
        brawler_column = 'brawler3'
    elif (map_filtered_data['P4'] == selected_player).any():
        brawler_column = 'brawler4'
    elif (map_filtered_data['P5'] == selected_player).any():
        brawler_column = 'brawler5'
    elif (map_filtered_data['P6'] == selected_player).any():
        brawler_column = 'brawler6'
    else:
        # If no matching position is found, return an empty figure
        empty_fig = px.bar(title="Le joueur n'est pas trouvé dans les colonnes P")
        return empty_fig

    # Count the occurrences of each Brawler played on the selected map
    brawler_counts = map_filtered_data[brawler_column].value_counts().reset_index()
    brawler_counts.columns = ['Brawler', 'Count']

    # Create the bar chart for the most played Brawlers
    team_fig = px.bar(brawler_counts, x='Brawler', y='Count', color='Brawler', title='Brawlers les plus joués sur la carte sélectionnée')

    return team_fig
@app.callback(
    Output('best-picks-against-graph', 'figure'),
    [Input('player-dropdown', 'value'),
     Input('map-dropdown', 'value')]
)
def update_best_picks_against_graph(selected_player, selected_map):
    # Liste des colonnes attendues pour les brawlers de l'équipe adverse
    opposing_brawler_columns = {
        'P1': ['brawler4', 'brawler5', 'brawler6'],
        'P2': ['brawler4', 'brawler5', 'brawler6'],
        'P3': ['brawler4', 'brawler5', 'brawler6'],
        'P4': ['brawler1', 'brawler2', 'brawler3'],
        'P5': ['brawler1', 'brawler2', 'brawler3'],
        'P6': ['brawler1', 'brawler2', 'brawler3']
    }

    # Vérifier la présence des colonnes nécessaires
    required_columns = ['P1', 'P2', 'P3', 'P4', 'P5', 'P6', 'map'] + [f'brawler{i}' for i in range(1, 7)]
    if not all(col in df.columns for col in required_columns):
        return px.bar(title="Colonnes manquantes dans les données")

    # Filtrer les données pour obtenir les lignes où le joueur sélectionné est dans les colonnes P
    player_filter = (
        (df['P1'] == selected_player) |
        (df['P2'] == selected_player) |
        (df['P3'] == selected_player) |
        (df['P4'] == selected_player) |
        (df['P5'] == selected_player) |
        (df['P6'] == selected_player)
    )
    filtered_data = df[player_filter]

    # Retourner un graphique vide si aucune donnée n'est trouvée
    if filtered_data.empty:
        return px.bar(title="Aucune donnée disponible pour le joueur sélectionné")

    # Filtrer les données par la carte sélectionnée
    map_filtered_data = filtered_data[filtered_data['map'] == selected_map]

    # Déterminer les colonnes des Brawlers en fonction de la position du joueur
    player_position = None
    for position in ['P1', 'P2', 'P3', 'P4', 'P5', 'P6']:
        if (map_filtered_data[position] == selected_player).any():
            player_position = position
            break

    # Si aucune position correspondante n'est trouvée, retourner un graphique vide
    if not player_position:
        return px.bar(title="Le joueur n'est pas trouvé dans les colonnes P")

    # Obtenir les colonnes des Brawlers de l'équipe adverse
    opposing_columns = opposing_brawler_columns[player_position]

    # Compter les occurrences de chaque Brawler joué contre le joueur
    brawler_counts = map_filtered_data[opposing_columns].melt(value_name='Brawler').dropna()['Brawler'].value_counts().reset_index()
    if brawler_counts.empty:
        return px.bar(title="Aucune donnée disponible pour les Brawlers contre le joueur sur la carte sélectionnée")

    brawler_counts.columns = ['Brawler', 'Count']

    # Créer le graphique en barres pour les Brawlers les plus joués contre le joueur
    try:
        against_fig = px.bar(brawler_counts, x='Brawler', y='Count', color='Brawler', title='Brawlers les plus joués contre le joueur sur la carte sélectionnée')
        return against_fig
    except Exception as e:
        return px.bar(title="Erreur lors de la création du graphique: " + str(e))



# Lancer l'application
if __name__ == '__main__':
    app.run_server(debug=True)

my css file :

h1{
    color:green
}

i think my question is a little bit dumb, but idk what can i do, can someone help me ?

Hi @Myro and welcome to the dash community :slightly_smiling_face:

That’s odd. Does it work for a very minimal example? Here’s one live on PyCafe that you could try:

hi ! thanks for your helping.
the code you send me work good, i download it on my pc and execute the python file, and the text is in green

1 Like

i tried other things but this didnt work

What didn’t work? Do you have some conflicting css? If you can provide a complete minimal example that replicates the issue, I might be able to help.

what do you mean by “conflicting css” ? the only thing i can see is that the css file isnt working, i only have one css file, here somes screensshot. as you can see, the header 1 isnt green so the file isnt working


I’d love to help, but I can’t debug a screenshot. :woman_shrugging:
Can you make a minimal example and post it on PyCafe?

hi ! im sorry, i created an exemple on pycafe without the 3 graphs, and the css is good, so i supposed there is a probleme in the 3 graphs
1st graph : “victory-by-mode-graph”
2nd graph : “best-picks-team-graph”
3rd graph : “best-picks-against-graph”
idk if this can help you but i created a pycafe without the 3 graphs
PyCafe

hmm - that’s odd. The graphs shouldn’t change the css of the other elements. Is there any way to duplicate the styling not working when you add a graph? It just looks like pretty typical bar charts - can you use some simple sample data?

hi ! i made this program with simple graphs, but this work

import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd

# Dictionnaire des cartes associées à chaque mode de jeu
mode_to_maps = {
    "Gem Grab": [
        "Hard Rock Mine", "Gem Fort", "Undermine", "Double Swoosh",
        "Minecart Madness", "Acute Angle", "Rustic Arcade", "Open Space",
        "Last Stop", "Sneaky Sneak", "Ahead Of The Curve", "Bear Trap"
    ],
    "Heist": [
        "Kaboom Canyon", "Safe Zone", "Hot Potato", "Bridge Too Far",
        "Diamond Dome", "Secret Or Mystery"
    ],
    "Hot Zone": [
        "Open Business", "Parallels Plays", "Ring of Fire",
        "Dueling Beetles", "Local Businesses", "Misty Meadows"
    ],
    "Bounty": [
        "Snake Prairie", "Shooting Star", "Hideout", "Canal Grande",
        "Flank Attack", "Crowd Strike"
    ],
    "Knockout": [
        "Goldarm Gulch", "Belles Rock", "Deep End", "Flaring Phoenix",
        "Out In The Open", "News Horizons", "Between The Rivers",
        "Four Levels", "Twilight Passage", "Hard Lane",
        "Island Hooping", "Sunset Spar"
    ],
    "Brawl Ball": [
        "Backyard Bowl", "Triple Dribble", "Sneaky Fields",
        "Super Beach", "Pinball Dreams", "Center Stage", "Beach Ball",
        "Sunny Soccer", "Penalty Kick", "Retina", "Offside Trap",
        "Back Pocket"
    ]
}

# Créer l'application Dash
app = dash.Dash(__name__)

# Mise en page de l'application
app.layout = html.Div([
    html.H1("Statistiques Brawl Stars"),

    # Menu déroulant pour sélectionner le mode de jeu
    html.Label("Sélectionner le mode de jeu"),
    dcc.Dropdown(
        id='mode-dropdown',
        options=[{'label': mode, 'value': mode} for mode in mode_to_maps.keys()],
        value=list(mode_to_maps.keys())[0],
        clearable=False
    ),

    # Menu déroulant pour sélectionner une carte (mis à jour en fonction du mode sélectionné)
    html.Label("Sélectionner la carte"),
    dcc.Dropdown(
        id='map-dropdown',
        clearable=False
    ),

    # Graphique des taux de victoire par mode de jeu
    dcc.Graph(id='victory-by-mode-graph'),

    # Graphique des meilleurs choix de l'équipe
    dcc.Graph(id='best-picks-team-graph'),

    # Graphique des meilleurs choix contre l'équipe
    dcc.Graph(id='best-picks-against-graph')
])

# Mettre à jour la liste des cartes en fonction du mode de jeu sélectionné
@app.callback(
    Output('map-dropdown', 'options'),
    Input('mode-dropdown', 'value')
)
def update_map_options(selected_mode):
    return [{'label': map_name, 'value': map_name} for map_name in mode_to_maps[selected_mode]]

# Générer des graphiques basés sur les données factices
@app.callback(
    [Output('victory-by-mode-graph', 'figure'),
     Output('best-picks-team-graph', 'figure'),
     Output('best-picks-against-graph', 'figure')],
    Input('mode-dropdown', 'value')
)
def update_graphs(selected_mode):
    # Données factices
    names = ["Player A", "Player B", "Player C"]
    values = [23, 17, 35]

    # Créer des graphiques de barres pour chaque graphique
    victory_fig = px.bar(x=names, y=values, labels={'x': 'Players', 'y': 'Victory Rate (%)'},
    title='Victory Rate by Player')
    best_picks_team_fig = px.bar(x=names, y=values, labels={'x': 'Players', 'y': 'Team Picks'},
    title='Best Picks for the Team')
    best_picks_against_fig = px.bar(x=names, y=values, labels={'x': 'Players', 'y': 'Counter Picks'},
    title='Best Picks Against the Team')

    return victory_fig, best_picks_team_fig, best_picks_against_fig

# Exécuter l'application
if __name__ == '__main__':
    app.run_server(debug=True)

Looks good!
In the code you posted on Pycafe there was a styles.css file in the root directory instead of the assets file. Dash will automatically include .css files from the assets folder only. Do you think that might have caused the problem originally?

the style.css in the root directory was a little mistake, on my pc, i have the style.css in the right folder

1 Like

did someone has an idea ?

the css file isnt loaded


After having deleted the cache, it work, Thanks you