1. Plotly 是什么?
Plotly 是一个 Python 库,专门用来创建交互式、出版物质量的可视化图表。与 Matplotlib 或 Seaborn 不同,Plotly 创建的图表不是静态图片,而是像网页一样可以互动的动态图表。
核心特点
- 交互性:可以缩放、平移、悬停查看详细信息
- 多样化图表:支持几乎所有常见和特殊的图表类型
- 美观:默认样式就很专业美观
- 多平台支持:可以在 Jupyter、网页应用、Dash 应用中运行
2. Plotly 能做什么?
房价趋势示例
import plotly.graph_objects as go
import plotly.express as px
# 创建简单的房价趋势图
fig = go.Figure()
# 添加不同区域的数据线
fig.add_trace(go.Scatter(
x=['1 月', '2 月', '3 月', '4 月', '5 月', '6 月'],
y=[50000, 52000, 53000, 55000, 57000, 59000],
mode='lines+markers',
name='市中心',
line=dict(color='red', width=3)
))
fig.add_trace(go.Scatter(
x=['1 月', '2 月', '3 月', '4 月', '5 月', '6 月'],
y=[30000, 31000, 32000, 33000, 34000, 36000],
mode='lines+markers',
name='郊区',
line=dict(color='blue', width=3)
))
# 设置图表布局
fig.update_layout(
title='上半年房价变化趋势',
xaxis_title='月份',
yaxis_title='平均房价(元/平米)',
hovermode='x unified'
)
fig.show()
3. 实际应用示例
示例 1:销售仪表板
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# 创建子图
fig = make_subplots(
rows=2, cols=2,
subplot_titles=('月度销售额', '产品销售占比', '地区分布', '销售趋势'),
specs=[[{'type': 'bar'}, {'type': 'pie'}], [{'type': 'choropleth'}, {'type': 'scatter'}]]
)
# 1. 柱状图:月度销售额
months = ['1 月', '2 月', '3 月', '4 月', '5 月', '6 月']
sales = [120, 135, 148, 165, 190, 210]
fig.add_trace(
go.Bar(x=months, y=sales, name='销售额', marker_color='lightblue'),
row=1, col=1
)
# 2. 饼图:产品占比
products = ['手机', '电脑', '平板', '配件']
percentages = [40, 30, 20, 10]
fig.add_trace(
go.Pie(labels=products, values=percentages, hole=0.3),
row=1, col=2
)
fig.update_layout(
title_text='2023 年上半年销售仪表板',
showlegend=True,
height=800
)
fig.show()
示例 2:疫情数据地图
import plotly.express as px
import pandas as pd
# 模拟数据
data = {
'城市': ['北京', '上海', '广州', '深圳', '成都', '武汉', '西安', '杭州'],
'纬度': [39.9, 31.2, 23.1, 22.5, 30.6, 30.6, 34.3, 30.3],
'经度': [116.4, 121.5, 113.3, 114.1, 104.1, 114.3, 108.9, 120.2],
'病例数': [500, 800, 300, 400, 200, 600, 150, 350],
'风险等级': ['高', '高', '中', '中', '低', '高', '低', '中']
}
df = pd.DataFrame(data)
# 创建气泡地图
fig = px.scatter_geo(df, lat='纬度', lon='经度', size='病例数', color='风险等级',
hover_name='城市', projection=,
title=, size_max=,
color_discrete_map={: , : , : })
fig.show()
4. 编程最佳实践
实践 1:两种 API 的选择
- Plotly Express:适合简单图表,快速生成。
- Graph Objects:适合复杂定制,精细控制。
# 方法 1:Plotly Express(快速模式)
import plotly.express as px
fig = px.scatter(df, x='身高', y='体重', color='性别', size='年龄', hover_data=['姓名'])
# 方法 2:Graph Objects(专业模式)
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Scatter(
x=df['身高'], y=df['体重'], mode='markers',
marker=dict(size=df['年龄']/3, color=df['性别'].map({'男': 'blue', '女': 'pink'}), opacity=0.7),
text=df['姓名'],
hovertemplate='<b>%{text}</b><br>身高:%{x}cm<br>体重:%{y}kg'
))
实践 2:数据准备先行
import pandas as pd
def prepare_sales_data(raw_data):
"""整理销售数据"""
df = pd.DataFrame(raw_data)
df = df.dropna()
df['销售额'] = df['单价'] * df['数量']
monthly_sales = df.groupby('月份')['销售额'].sum().reset_index()
return monthly_sales
sales_data = prepare_sales_data(raw_data)
fig = px.line(sales_data, x='月份', y='销售额')
实践 3:性能优化
当数据点很多时(超过一万条),可采取以下策略:
- 抽样:
large_df.sample(n=5000) - 聚合:将连续数据分箱后聚合。
- WebGL 加速:使用
go.Scattergl。
fig = go.Figure(data=go.Scattergl(x=large_df['x'], y=large_df['y'], mode='markers'))
实践 4:可复用配置
MY_THEME = {
'layout': {
'font': {'family': 'Arial', 'size': 14},
'plot_bgcolor': 'white',
'paper_bgcolor': 'white',
'title': {'x': 0.5, 'xanchor': 'center'},
'margin': {'l': 50, 'r': 50, 't': 80, 'b': 50}
},
'colors': ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']
}
def create_chart(data, chart_type='line'):
if chart_type == 'line':
fig = px.line(data)
elif chart_type == 'bar':
fig = px.bar(data)
fig.update_layout(**MY_THEME['layout'])
return fig
5. 最佳使用场景
- 数据探索与发现:在 Jupyter Notebook 中初步分析数据,交互式探索模式和异常。
- 商业报告与演示:制作动态业务报告,客户可自行交互探索。
- 仪表板应用:实时监控系统(搭配 Dash 框架),实时更新,多图表联动。
- 科学研究:论文、研究报告中的复杂可视化,支持 3D、等高线等。
6. 常见陷阱与解决方案
- 过度复杂的图表:使用子图或仪表板分开显示。
- 忽略响应式设计:设置
autosize=True和自适应 margin。 - 颜色使用不当:使用色盲友好调色板(如
px.colors.colorbrewer.Set3)。
总结
Plotly 让专业的数据可视化变得平民化:
- 简单任务:用 Plotly Express 快速搞定
- 复杂需求:用 Graph Objects 精细控制
- 交互需求:默认支持缩放、悬停、选择
- 分享需求:可以导出为 HTML、图片或嵌入网页
决策流程:
- 需要快速探索数据?→ Plotly Express
- 需要高度定制化?→ Graph Objects
- 需要实时交互仪表板?→ Plotly + Dash
- 需要嵌入网页?→ 导出为 HTML


