Skip to main content 首页 创作者 johnnuwan eva_core plotly
plotly Plotly / Dash : bibliothèque de visualisation interactive Python et JavaScript — graphiques 3D, cartes, animations, Dashboards complets avec callbacks Python.
跳到安装 Skills Marketplace 发现并探索由社区构建的 Agent Skills
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/JohnNuwan/EVA_CORE --skill plotly命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
下载 Zip 下载中... name plotly description Plotly / Dash : bibliothèque de visualisation interactive Python et JavaScript — graphiques 3D, cartes, animations, Dashboards complets avec callbacks Python. version 1.0.0 author EVA license Privée EVA platforms ["linux","macos","windows"] metadata {"EVA":{"tags":["plotly","dash","plotly-express","interactive","dataviz","python","dashboard","3d","geo"],"homepage":"https://plotly.com/","related_skills":["d3-js","chart-js","dashboard-design","data-analysis-exploration"]}} prerequisites {"commands":["python3","pip"],"pip_packages":["plotly","dash","pandas","numpy"]}
Compétence Plotly / Dash — Visualisations Interactives & Dashboards Python
Vue d'ensemble
Plotly est une bibliothèque de visualisation interactive multi-langage (Python, R, Julia, JS) qui produit des graphiques prêts pour le web avec zoom, pan, tooltips, et animations intégrés. Plotly Express fournit une API concise (~20 fonctions) pour les graphiques courants. Dash est le framework de dashboarding Python construit sur Plotly, permettant de créer des applications web interactives entièrement en Python.
Philosophie : "Du DataFrame au graphique interactif en une ligne de code."
Architecture : Plotly convertit les données en JSON (spec Figure), qui est rendu en D3.js/React dans le navigateur. Tout est interactif par défaut.
Quand l'utiliser
Activez cette compétence lorsque l'utilisateur :
Veut explorer des données en Python avec des graphiques interactifs (zoom, pan, hover).
A besoin de graphiques 3D (surface, scatter3d, mesh3d).
Construit une application Dashboard Python avec Dash.
Souhaite des animations temporelles (play/pause sur des frames).
Veux exporter des graphiques vers HTML/PNG/SVG/PDF.
A besoin de cartes interactives (scattergeo, choropleth, mapbox).
Prérequis
pip install plotly dash pandas numpy
1. Plotly Express — API Haute-Niveau
1.1 Nuage de Points (Scatter)
import plotly.express as px
df = px.data.iris()
fig = px.scatter(
df,
x="sepal_width" ,
y="sepal_length" ,
color="species" ,
size="petal_length" ,
hover_data=["petal_width" ],
title="Iris : Largeur vs Longueur des Sépales" ,
labels={"sepal_width" : "Largeur (cm)" , "sepal_length" : "Longueur (cm)" },
trendline="ols" ,
)
fig.show()
1.2 Ligne et Série Temporelle
import pandas pd
df = px.data.gapminder().query( )
fig = px.line(
df,
x= ,
y= ,
title= ,
markers= ,
line_shape= ,
)
fig.update_traces(line= (width= ))
fig.show()
as
"country == 'France'"
"year"
"gdpPercap"
"PIB par Habitant — France"
True
"spline"
dict
3
1.3 Barres df = px.data.tips()
fig = px.bar(
df,
x="day" ,
y="total_bill" ,
color="sex" ,
barmode="group" ,
title="Addition par Jour et Sexe" ,
text_auto=".2s" ,
)
fig.update_traces(textposition="outside" )
fig.show()
fig = px.bar(df, x="total_bill" , y="day" , orientation="h" , color="time" )
1.4 Histogramme, Boxplot, Violin
fig = px.histogram(df, x="total_bill" , color="sex" , nbins=30 , marginal="box" )
fig = px.box(df, x="day" , y="total_bill" , color="sex" , notched=True , points="all" )
fig = px.violin(df, x="day" , y="total_bill" , color="sex" , box=True , points="all" )
1.5 Matrice de Corrélation (Heatmap) import plotly.figure_factory as ff
corr = df.select_dtypes("number" ).corr()
fig = ff.create_annotated_heatmap(
corr.values,
x=list (corr.columns),
y=list (corr.index),
colorscale="RdBu_r" ,
annotation_text=corr.round (2 ).values,
)
fig.update_layout(title="Matrice de Corrélations" )
fig.show()
1.6 Carte Choroplèthe
df = px.data.gapminder().query("year == 2007" )
fig = px.choropleth(
df,
locations="iso_alpha" ,
color="gdpPercap" ,
hover_name="country" ,
color_continuous_scale=px.colors.sequential.Plasma,
title="PIB par Habitant (2007)" ,
projection="natural earth" ,
)
fig.show()
fig = px.choropleth(
df_states,
locations="state" ,
locationmode="USA-states" ,
color="unemployment" ,
scope="usa" ,
)
2. Graphiques 3D
fig = px.scatter_3d(
df,
x="sepal_length" ,
y="sepal_width" ,
z="petal_length" ,
color="species" ,
size="petal_width" ,
opacity=0.7 ,
title="Iris — 3 Dimensions" ,
)
import numpy as np
x = np.arange(-5 , 5 , 0.1 )
y = np.arange(-5 , 5 , 0.1 )
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2 ))
fig = go.Figure(data=[go.Surface(z=Z, x=x, y=y, colorscale="Viridis" )])
fig.update_layout(title="Surface sin(r)/r" , scene=dict (
xaxis_title="X" , yaxis_title="Y" , zaxis_title="Z"
))
fig = px.line_3d(df, x="x" , y="y" , z="z" , color="trajectory" )
3. Graphiques Avancés (API Graph Objects) Pour un contrôle fin, utiliser plotly.graph_objects :
import plotly.graph_objects as go
from plotly.subplots import make_subplots
fig = make_subplots(
rows=2 , cols=2 ,
subplot_titles=("Scatter" , "Barres" , "Carte" , "3D" ),
specs=[
[{"type" : "scatter" }, {"type" : "bar" }],
[{"type" : "scattergeo" }, {"type" : "scene" }],
],
)
fig.add_trace(go.Scatter(x=[1 ,2 ,3 ], y=[4 ,5 ,6 ], mode="lines+markers" ), row=1 , col=1 )
fig.add_trace(go.Bar(x=["A" ,"B" ,"C" ], y=[10 ,20 ,15 ]), row=1 , col=2 )
fig.add_trace(go.Scattergeo(lon=[2.35 ], lat=[48.85 ], mode="markers" ), row=2 , col=1 )
fig.add_trace(go.Scatter3d(x=[0 ,1 ,2 ], y=[0 ,1 ,2 ], z=[0 ,1 ,2 ]), row=2 , col=2 )
fig.update_layout(title="Dashboard Multi-Graphiques" , showlegend=False )
fig.show()
3.1 Candlestick (Finance) fig = go.Figure(data=[go.Candlestick(
x=df["date" ],
open =df["open" ], high=df["high" ],
low=df["low" ], close=df["close" ],
)])
fig.update_layout(
title="OHLC — BTC/USD" ,
xaxis_rangeslider_visible=False ,
yaxis_title="Prix (USD)" ,
)
3.2 Sankey (Diagramme de Flux) fig = go.Figure(data=[go.Sankey(
node=dict (
label=["Source A" , "Source B" , "Étape 1" , "Étape 2" , "Final" ],
color=["blue" , "green" , "gray" , "gray" , "red" ],
),
link=dict (
source=[0 , 0 , 1 , 2 , 2 , 3 ],
target=[2 , 3 , 3 , 3 , 4 , 4 ],
value=[8 , 4 , 6 , 5 , 7 , 9 ],
)
)])
fig.update_layout(title="Diagramme Sankey — Flux de Données" )
3.3 Funnel (Entonnoir) fig = go.Figure(go.Funnel(
y=["Visiteurs" , "Inscrits" , "Actifs" , "Payants" ],
x=[10000 , 2500 , 800 , 120 ],
textinfo="value+percent initial" ,
marker=dict (color=["#636efa" , "#ef553b" , "#00cc96" , "#ab63fa" ]),
))
fig.update_layout(title="Entonnoir de Conversion" )
3.4 Waterfall fig = go.Figure(go.Waterfall(
name="P&L" ,
orientation="v" ,
measure=["relative" , "relative" , "total" , "relative" , "total" ],
x=["Revenus" , "Coûts" , "Marge Brute" , "Taxes" , "Bénéfice Net" ],
y=[100000 , -40000 , None , -15000 , None ],
connector={"line" : {"color" : "rgb(63, 63, 63)" }},
))
fig.update_layout(title="Compte de Résultat" )
4. Animations
4.1 Animation par Frames (Temporal) df = px.data.gapminder()
fig = px.scatter(
df,
x="gdpPercap" ,
y="lifeExp" ,
size="pop" ,
color="continent" ,
animation_frame="year" ,
animation_group="country" ,
log_x=True ,
size_max=60 ,
range_x=[100 , 100000 ],
range_y=[25 , 90 ],
title="Développement Mondial (1952-2007)" ,
)
fig.show()
4.2 Animation avec Slider Personnalisé import numpy as np
frames = []
for t in np.linspace(0 , 2 *np.pi, 50 ):
x = np.cos(t + np.linspace(0 , 2 *np.pi, 20 ))
y = np.sin(t + np.linspace(0 , 2 *np.pi, 20 ))
frames.append(go.Frame(data=[go.Scatter(x=x, y=y, mode="markers" )]))
fig = go.Figure(
data=[go.Scatter(x=[], y=[], mode="markers" )],
layout=go.Layout(
title="Animation Sinusoïdale" ,
updatemenus=[{
"type" : "buttons" ,
"buttons" : [{"label" : "▶" , "method" : "animate" , "args" : [None ]},
{"label" : "⏸" , "method" : "animate" , "args" : [[None ], {"mode" : "immediate" }]}],
}],
sliders=[{
"steps" : [{"args" : [[f.name]], "label" : f.name, "method" : "animate" }
for f in frames],
}]
),
frames=frames,
)
5. Dash — Applications Web
5.1 Application Minimale from dash import Dash, html, dcc, Input, Output
import plotly.express as px
app = Dash(__name__)
df = px.data.iris()
app.layout = html.Div([
html.H1("Dashboard Iris" , style={"textAlign" : "center" }),
dcc.Dropdown(
id ="x-variable" ,
options=[{"label" : c, "value" : c} for c in df.columns[:4 ]],
value="sepal_length" ,
),
dcc.Graph(id ="scatter-plot" ),
])
@app.callback(
Output("scatter-plot" , "figure" ),
Input("x-variable" , "value" ),
)
def update_chart (x_var ):
fig = px.scatter(df, x=x_var, y="petal_length" , color="species" )
return fig
if __name__ == "__main__" :
app.run_server(debug=True , port=8050 )
5.2 Layouts et Composants app.layout = html.Div([
html.Header([
html.H1("Dashboard Ventes" ),
html.Nav([
dcc.Link("Accueil" , href="/" ),
dcc.Link("Analyse" , href="/analyse" ),
])
]),
html.Main([
html.Div([
html.Div([
html.H3("Filtres" ),
dcc.Dropdown(id ="region" , options=[...], multi=True ),
dcc.DatePickerRange(id ="date-range" ),
dcc.RangeSlider(id ="amount-range" , min =0 , max =10000 ),
html.Button("Réinitialiser" , id ="reset-btn" ),
], className="sidebar" ),
html.Div([
dcc.Graph(id ="line-chart" ),
dcc.Graph(id ="bar-chart" ),
], className="main-content" ),
], className="row" ),
]),
html.Footer(id ="last-update" ),
])
dcc.Tabs([
dcc.Tab(label="Vue d'ensemble" , children=[...]),
dcc.Tab(label="Analyse détaillée" , children=[...]),
dcc.Tab(label="Export" , children=[...]),
])
dcc.Store(id ="filtered-data" , storage_type="memory" )
5.3 Callbacks Avancés
@app.callback(
Output("line-chart" , "figure" ),
Output("bar-chart" , "figure" ),
Output("kpi-text" , "children" ),
Input("region" , "value" ),
Input("date-range" , "start_date" ),
Input("date-range" , "end_date" ),
prevent_initial_call=False ,
)
def update_dashboard (regions, start_date, end_date ):
df_filtered = df.copy()
if regions:
df_filtered = df_filtered[df_filtered["region" ].isin(regions)]
if start_date:
df_filtered = df_filtered[df_filtered["date" ] >= start_date]
line_fig = px.line(df_filtered, x="date" , y="sales" , color="region" )
bar_fig = px.bar(df_filtered, x="product" , y="sales" )
kpi = f"Ventes totales : {df_filtered['sales' ].sum ():,.0 f} €"
return line_fig, bar_fig, kpi
@app.callback(
Output("sub-product" , "options" ),
Input("product" , "value" ),
)
def update_sub_products (product ):
return [{"label" : p, "value" : p} for p in df[df["product" ] == product]["sub_product" ].unique()]
@app.callback(
Output({"type" : "graph" , "index" : MATCH}, "figure" ),
Input({"type" : "dropdown" , "index" : MATCH}, "value" ),
)
def update_dynamic_graph (variable ):
return px.histogram(df, x=variable)
app.clientside_callback(
"""
function(value) {
return document.title = "Dashboard - " + value;
}
""" ,
Output("page-title" , "children" ),
Input("region" , "value" ),
)
5.4 Composants Avancés
from dash import dash_table
dash_table.DataTable(
id ="table" ,
columns=[{"name" : c, "id" : c, "type" : "numeric" if df[c].dtype in ["int64" , "float64" ] else "text" } for c in df.columns],
data=df.to_dict("records" ),
page_size=20 ,
sort_action="native" ,
filter_action="native" ,
row_selectable="multi" ,
style_table={"overflowX" : "auto" },
style_cell={"textAlign" : "left" , "padding" : "8px" },
style_header={"fontWeight" : "bold" , "backgroundColor" : "#f8f9fa" },
style_data_conditional=[
{"if" : {"row_index" : "odd" }, "backgroundColor" : "#f8f9fa" },
],
)
dcc.Graph(id ="main-chart" , config={
"scrollZoom" : True ,
"displayModeBar" : True ,
"displaylogo" : False ,
"modeBarButtonsToRemove" : ["sendDataToCloud" ],
"modeBarButtonsToAdd" : ["drawline" , "drawopenpath" , "eraseshape" ],
})
dcc.Interval(id ="refresh-interval" , interval=60 *1000 , n_intervals=0 )
5.5 Thèmes et Style
import dash_bootstrap_components as dbc
app = Dash(external_stylesheets=[dbc.themes.DARKLY])
app.layout = dbc.Container([
dbc.Row([
dbc.Col(html.H1("Dashboard" ), width=12 ),
]),
dbc.Row([
dbc.Col([
dbc.Card([
dbc.CardHeader("Filtres" ),
dbc.CardBody([...]),
]),
], width=3 ),
dbc.Col([
dcc.Graph(id ="chart" ),
], width=9 ),
]),
])
6. Export et Déploiement
fig.write_html("graphique.html" , include_plotlyjs="cdn" , full_html=False )
fig.write_image("graphique.png" , width=1200 , height=800 , scale=2 )
fig.write_image("graphique.svg" )
fig.write_image("graphique.pdf" )
gunicorn app:server -b 0.0 .0 .0 :8050 -w 4
FROM python:3.11
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
EXPOSE 8050
CMD ["gunicorn" , "app:server" , "-b" , "0.0.0.0:8050" ]
web: gunicorn app:server
Pièges Courants (Pitfalls)
Graphique vide dans Dash.
Erreur : Le callback retourne None accidentellement.
Correction : Toujours retourner une figure Plotly valide, jamais None. Utiliser return dash.no_update pour éviter un reset.
Callbacks en boucle infinie.
Erreur : Output A dépend de Input B, et Output B dépend de Input A.
Correction : Vérifier les dépendances croisées. Utiliser prevent_initial_call=True si nécessaire.
Lenteur avec de gros DataFrames.
Erreur : Passer un DataFrame de 100 000 lignes dans un callback — il est sérialisé en JSON à chaque appel.
Correction : Utiliser dcc.Store côté client, ou agréger les données avant de les passer à Plotly.
Carte vide sans erreur.
Erreur : Les codes pays dans locations ne correspondent pas au format attendu (iso_alpha vs country names).
Correction : Vérifier le paramètre locationmode : ISO-3 (défaut), USA-states, country names.
Dash qui ne marche pas en production.
Erreur : app.run_server(debug=True) utilisé en prod.
Correction : Utiliser Gunicorn/WSGI : gunicorn app:server. En développement, debug=True est OK.
Export PNG qui échoue.
Erreur : write_image nécessite kaleido ou orca installé.
Correction : pip install -U kaleido ou conda install -c plotly plotly-orca.
Ressources
Checklist