Lý thuyết
Bài 9/14

Plotly - Interactive Visualization

Tạo biểu đồ tương tác với Plotly Express và Plotly Graph Objects

Plotly - Interactive Visualization

1. Giới thiệu Plotly

Plotly tạo biểu đồ interactive - có thể zoom, pan, hover, click!

FeatureMatplotlib/SeabornPlotly
Interactive❌ Static✅ Interactive
Web-based✅ HTML/JS
3D plotsLimited✅ Excellent
AnimationsComplex✅ Easy
Dashboards✅ Dash framework
Python
1import plotly.express as px
2import plotly.graph_objects as go
3import pandas as pd
4import numpy as np
5
6# Sample data
7df = px.data.gapminder()
8tips = px.data.tips()

2. Plotly Express - Quick Plots

2.1 Scatter Plot

Python
1# Basic scatter
2fig = px.scatter(df.query("year == 2007"),
3 x="gdpPercap", y="lifeExp",
4 color="continent", size="pop",
5 hover_name="country",
6 log_x=True,
7 title="GDP vs Life Expectancy (2007)")
8fig.show()
9
10# Với trendline
11fig = px.scatter(tips, x="total_bill", y="tip",
12 trendline="ols",
13 trendline_color_override="red")
14fig.show()

2.2 Line Plot

Python
1# Time series line plot
2df_filtered = df[df['country'].isin(['Vietnam', 'Japan', 'United States'])]
3
4fig = px.line(df_filtered, x="year", y="gdpPercap",
5 color="country",
6 title="GDP Per Capita Over Time",
7 markers=True)
8fig.show()
9
10# Multiple Y axes
11fig = px.line(df_filtered, x="year", y=["gdpPercap", "lifeExp"],
12 color="country", facet_col="variable")
13fig.show()

2.3 Bar Chart

Python
1# Bar chart
2fig = px.bar(df.query("year == 2007 and continent == 'Asia'").nlargest(10, 'pop'),
3 x="country", y="pop",
4 color="lifeExp",
5 title="Top 10 Most Populous Asian Countries")
6fig.show()
7
8# Grouped bar
9fig = px.bar(tips, x="day", y="total_bill", color="sex",
10 barmode="group",
11 title="Total Bill by Day and Sex")
12fig.show()
13
14# Stacked bar
15fig = px.bar(tips, x="day", y="total_bill", color="sex",
16 barmode="stack")
17fig.show()

2.4 Histogram

Python
1# Histogram
2fig = px.histogram(tips, x="total_bill", nbins=30,
3 color="time",
4 marginal="box", # "rug", "violin", "box"
5 title="Distribution of Total Bill")
6fig.show()

2.5 Box và Violin

Python
1# Box plot
2fig = px.box(tips, x="day", y="total_bill", color="smoker",
3 notched=True,
4 title="Total Bill Distribution by Day")
5fig.show()
6
7# Violin plot
8fig = px.violin(tips, x="day", y="total_bill", color="sex",
9 box=True, points="all",
10 title="Violin Plot")
11fig.show()

3. Pie và Donut Charts

Python
1# Pie chart
2continent_pop = df.query("year == 2007").groupby("continent")["pop"].sum().reset_index()
3
4fig = px.pie(continent_pop, values="pop", names="continent",
5 title="World Population by Continent (2007)",
6 hole=0) # hole=0.4 for donut
7fig.show()
8
9# Sunburst (hierarchical pie)
10fig = px.sunburst(df.query("year == 2007"),
11 path=["continent", "country"],
12 values="pop",
13 title="Population Sunburst")
14fig.show()

4. Heatmap và Choropleth

4.1 Heatmap

Python
1# Correlation heatmap
2numeric_tips = tips.select_dtypes(include=[np.number])
3corr = numeric_tips.corr()
4
5fig = px.imshow(corr,
6 text_auto=True,
7 color_continuous_scale="RdBu_r",
8 title="Correlation Heatmap")
9fig.show()

4.2 Choropleth Map

Python
1# World map
2fig = px.choropleth(df.query("year == 2007"),
3 locations="iso_alpha",
4 color="lifeExp",
5 hover_name="country",
6 color_continuous_scale="Viridis",
7 title="Life Expectancy by Country (2007)")
8fig.show()
9
10# USA map
11fig = px.choropleth(locations=["CA", "TX", "NY", "FL"],
12 locationmode="USA-states",
13 color=[1, 2, 3, 4],
14 scope="usa")
15fig.show()

5. 3D Plots

Python
1# 3D Scatter
2fig = px.scatter_3d(df.query("year == 2007"),
3 x="gdpPercap", y="lifeExp", z="pop",
4 color="continent",
5 size="pop",
6 hover_name="country",
7 log_x=True, log_z=True,
8 title="3D Scatter Plot")
9fig.show()
10
11# 3D Surface
12x = np.linspace(-5, 5, 50)
13y = np.linspace(-5, 5, 50)
14X, Y = np.meshgrid(x, y)
15Z = np.sin(np.sqrt(X**2 + Y**2))
16
17fig = go.Figure(data=[go.Surface(z=Z, x=X, y=Y)])
18fig.update_layout(title="3D Surface Plot")
19fig.show()

6. Animations

Python
1# Animated scatter (by year)
2fig = px.scatter(df, x="gdpPercap", y="lifeExp",
3 animation_frame="year",
4 animation_group="country",
5 size="pop", color="continent",
6 hover_name="country",
7 log_x=True,
8 size_max=55,
9 range_x=[100, 100000],
10 range_y=[25, 90],
11 title="Gapminder Animation")
12fig.show()
13
14# Animated bar
15fig = px.bar(df, x="continent", y="pop",
16 animation_frame="year",
17 color="continent",
18 range_y=[0, 4e9])
19fig.show()

7. Subplots với Plotly Express

Python
1# Facet plots
2fig = px.scatter(tips, x="total_bill", y="tip",
3 color="smoker",
4 facet_col="time",
5 facet_row="sex",
6 title="Faceted Scatter Plot")
7fig.show()
8
9# Facet wrap
10fig = px.histogram(df.query("year == 2007"),
11 x="lifeExp",
12 facet_col="continent",
13 facet_col_wrap=3)
14fig.show()

8. Graph Objects - Advanced Control

8.1 Custom Figure

Python
1# Tạo figure từ scratch
2fig = go.Figure()
3
4# Thêm traces
5fig.add_trace(go.Scatter(
6 x=[1, 2, 3, 4],
7 y=[10, 11, 12, 13],
8 mode='lines+markers',
9 name='Line 1'
10))
11
12fig.add_trace(go.Scatter(
13 x=[1, 2, 3, 4],
14 y=[12, 9, 15, 12],
15 mode='lines+markers',
16 name='Line 2'
17))
18
19# Customize layout
20fig.update_layout(
21 title="Custom Plot",
22 xaxis_title="X Axis",
23 yaxis_title="Y Axis",
24 legend_title="Legend"
25)
26
27fig.show()

8.2 Multiple Y-Axes

Python
1fig = go.Figure()
2
3fig.add_trace(go.Scatter(
4 x=[1, 2, 3, 4],
5 y=[100, 200, 300, 400],
6 name="Revenue",
7 yaxis="y1"
8))
9
10fig.add_trace(go.Bar(
11 x=[1, 2, 3, 4],
12 y=[10, 20, 15, 25],
13 name="Orders",
14 yaxis="y2"
15))
16
17fig.update_layout(
18 yaxis=dict(title="Revenue ($)", side="left"),
19 yaxis2=dict(title="Orders", side="right", overlaying="y"),
20 title="Dual Y-Axis Chart"
21)
22
23fig.show()

8.3 Subplots với make_subplots

Python
1from plotly.subplots import make_subplots
2
3fig = make_subplots(rows=2, cols=2,
4 subplot_titles=("Plot 1", "Plot 2", "Plot 3", "Plot 4"))
5
6fig.add_trace(go.Scatter(x=[1,2,3], y=[4,5,6]), row=1, col=1)
7fig.add_trace(go.Bar(x=[1,2,3], y=[2,3,5]), row=1, col=2)
8fig.add_trace(go.Scatter(x=[1,2,3], y=[1,2,3], mode='lines'), row=2, col=1)
9fig.add_trace(go.Histogram(x=np.random.randn(500)), row=2, col=2)
10
11fig.update_layout(height=600, title_text="Subplots")
12fig.show()

9. Customization

9.1 Colors và Themes

Python
1# Custom colors
2fig = px.scatter(tips, x="total_bill", y="tip", color="day",
3 color_discrete_sequence=px.colors.qualitative.Set2)
4fig.show()
5
6# Templates/Themes
7templates = ["plotly", "plotly_white", "plotly_dark",
8 "ggplot2", "seaborn", "simple_white"]
9
10for template in templates:
11 fig = px.scatter(tips, x="total_bill", y="tip",
12 template=template, title=f"Template: {template}")
13 fig.show()

9.2 Annotations

Python
1fig = px.scatter(tips, x="total_bill", y="tip")
2
3# Add annotation
4fig.add_annotation(
5 x=50, y=10,
6 text="High tip!",
7 showarrow=True,
8 arrowhead=1
9)
10
11# Add shape
12fig.add_shape(
13 type="line",
14 x0=0, y0=0, x1=50, y1=10,
15 line=dict(color="Red", dash="dash")
16)
17
18fig.show()

9.3 Export

Python
1# Save as HTML (interactive)
2fig.write_html("chart.html")
3
4# Save as image (static)
5fig.write_image("chart.png")
6fig.write_image("chart.pdf")
7fig.write_image("chart.svg")

10. Dashboard Preview với Dash

Python
1# Dash - Full interactive dashboards
2# pip install dash
3
4from dash import Dash, html, dcc
5import plotly.express as px
6
7app = Dash(__name__)
8
9fig = px.scatter(tips, x="total_bill", y="tip", color="day")
10
11app.layout = html.Div([
12 html.H1("My Dashboard"),
13 dcc.Graph(figure=fig),
14 dcc.Dropdown(
15 options=['Sun', 'Sat', 'Thur', 'Fri'],
16 value='Sun'
17 )
18])
19
20if __name__ == '__main__':
21 app.run_server(debug=True)

11. Quick Reference

Python
1# Common Plotly Express functions
2px.scatter() # Scatter plot
3px.line() # Line plot
4px.bar() # Bar chart
5px.histogram() # Histogram
6px.box() # Box plot
7px.violin() # Violin plot
8px.pie() # Pie chart
9px.sunburst() # Sunburst (hierarchical)
10px.treemap() # Treemap
11px.choropleth() # Map
12px.scatter_3d() # 3D scatter
13px.imshow() # Heatmap
14
15# Common parameters
16x, y # Data columns
17color # Color by category
18size # Size by value
19hover_name # Hover text
20facet_col # Column faceting
21facet_row # Row faceting
22animation_frame # Animation
23template # Theme
24title # Chart title

Tổng Kết

Trong bài này, bạn đã học:

  • ✅ Plotly Express cho quick plots
  • ✅ Scatter, Line, Bar, Histogram, Box plots
  • ✅ Pie charts và Sunburst
  • ✅ Heatmaps và Choropleth maps
  • ✅ 3D visualizations
  • ✅ Animations
  • ✅ Graph Objects cho advanced control
  • ✅ Subplots và customization

Bài tiếp theo: Streamlit - Build Data Apps!