python3可视化之plotly基本使用

Plotly是一个功能强大的Python交互式可视化库。Plotly的动态可视化功能主要基于 JavaScript 和 Web 浏览器的交互能力。通过Plotly创建图表时,Plotly会将图表数据和配置信息转换为 JSON 格式,并通过 Plotly.js 在浏览器中渲染图表。

安装 pip install plotly

保存为图片需安装  :pip install kaleido==0.1.*
 
核心特性:
交互性‌:支持缩放、平移、悬停查看数据详情等功能,用户可直接与图表互动。
‌双接口设计‌:‌Plotly Express (px)‌:高级接口,语法简洁(类似 Seaborn),快速创建常见图表。‌Graph Objects (go)‌:低级接口,提供精细化控制,适合定制复杂图表。
‌多样化图表‌:支持 ‌40+ 图表类型‌,包括散点图、3D图、热力图、地图、箱线图等。
 

常用配置


import plotly.graph_objects as go
import plotly.io as pio

x = [1, 2, 3, 4, 5]
y = [i + 60 for i in x]
c = [[i + 5, i - 5] for i in y]
fig = go.Figure(
    data=[
        go.Scatter(
            x=x,
            y=y,
            mode="markers+lines",
            customdata=c,  # 传递额外数据
            hovertemplate="<b>%{meta[1]}</b> 观测值<br>"  # 鼠标悬停模板
            + "X轴: %{x}<br>"
            + "Y轴: %{y:.2f}<br>"  # 数值格式化
            + "max: %{customdata[0]}%<br>"
            + "min: %{customdata[1]}%<br>"
            + "日期: %{meta[0]|%Y-%m-%d}<br>",  # 日期格式化
        )
    ]
)
fig.update_layout(
    title={
        "text": "标题",
        "font": {"family": "Arial", "size": 24, "color": "black"},
        "x": 0.90,
        "xanchor": "right",
    },
    xaxis={
        "title": "X轴标签",
        "tickangle": 45,
        "title_standoff": 25,  # title_standoff调整标签与轴线之间的距离
        "range": [0, 6],  # 坐标轴范围
        "autorange": False,  # autorange关闭自动缩放
        "dtick": 2,  # 坐标轴刻度间隔
    },
    yaxis_range=[60, 66],
    yaxis_dtick=1,
    hoverlabel={
        "bgcolor": "rgba(255,255,255,0.9)",
        "font_size": 12,
    },  # 悬停提示框的样式
)
fig.update_traces(
    meta=[
        ["2025-04-13", "A"],
        ["2025-04-16", "B"],
        ["2025-04-16", "A"],
        ["2025-04-15", "B"],
        ["2025-04-17", "C"],
    ]
)  # 元数据注入
config = {
    "displaylogo": False,  # 隐藏Plotly官方logo
    "scrollZoom": True,  # 开启鼠标滚轮缩放
}
fig.show(config=config)  # 显示图表

pio.write_image(fig, "../../charts/figure.png")  # 保存为PNG
pio.write_image(fig, "../../charts/figure_highres.png", scale=2)  # 保存为高分辨率PNG,scale值越大分辨率越高
pio.write_image(fig, "../../charts/figure.jpg")  # 保存为JPEG
pio.write_image(fig, "../../charts/figure.pdf")  # 保存为PDF

显示

散点图

import plotly.express as px
import pandas as pd
import plotly.io as pio
import plotly.figure_factory as ff

tips = pd.read_csv("../../seaborn-data-master/tips.csv")
fig = px.scatter(tips, x="total_bill", y="tip", title="账单金额-小费", color="sex")
pio.write_image(fig, "../../charts/scatter-px.png")

# 多子图
fig = px.scatter(tips, x="total_bill", y="tip", facet_col="day", facet_row="time")
pio.write_image(fig, "../../charts/scatter-px-facet.png")


df = pd.read_csv("../../seaborn-data-master/car_crashes.csv")
# 气泡图
fig = px.scatter(df, x="speeding", y="alcohol", size="total", title="car crashes")
pio.write_image(fig, "../../charts/scatter-bubble-px.png")

# 散点矩阵图:展示多变量之间的相关性
fig = ff.create_scatterplotmatrix(
    df,
    diag="histogram",
    width=1200,
    height=1200,
)
pio.write_image(fig, "../../charts/scatter-matrix-px.png")

 普通散点图

 多子图

气泡图

散点矩阵图
graph_objects接口
import plotly.graph_objects as go
import pandas as pd
import plotly.io as pio

tips = pd.read_csv("../../seaborn-data-master/tips.csv")
df_m = tips.query("sex=='Male'")
df_f = tips.query("sex=='Female'")
traces = [
    go.Scatter(x=df_m["total_bill"], y=df_m["tip"], mode="markers", name="Male"),
    go.Scatter(x=df_f["total_bill"], y=df_f["tip"], mode="markers", name="Female"),
]
layout = go.Layout(
    title="账单金额-小费",
    xaxis_title="total_bill",
    yaxis_title="tip",
)
fig = go.Figure(data=traces, layout=layout)
pio.write_image(fig, "../../charts/scatter-go.png")

 折线图

import plotly.express as px
import pandas as pd
import plotly.io as pio

df = pd.read_csv("../../seaborn-data-master/healthexp.csv")
fig = px.line(df, x="Year", y="Life_Expectancy", color="Country")
fig.update_xaxes(title_text="国家")  # 设置 X 轴标签
fig.update_yaxes(title_text="平均寿命")  # 设置 Y 轴标签
fig.update_xaxes(tickangle=45, tickfont=dict(size=10))  # 调整 X 轴刻度角度和字体大小
fig.update_yaxes(dtick=5, tickfont=dict(size=10))  # 设置 Y 轴刻度间隔和字体大小
fig.update_yaxes(range=[65, 90])  # 设置 Y 轴范围
pio.write_image(fig, "../../charts/line-px.png")

 

graph_objects接口

import plotly.graph_objects as go
import pandas as pd
import plotly.io as pio

df = pd.read_csv("../../seaborn-data-master/healthexp.csv")
countries = df["Country"].unique()
data_country = [df.query(f"Country=='{c}'") for c in countries]

# 图例分组
traces = [go.Scatter(x=df_c["Year"], y=df_c["Spending_USD"], name=countries[i], legendgroup=countries[i]) for i, df_c in enumerate(data_country)]
traces = traces + [
    go.Scatter(x=df_c["Year"], y=df_c["Life_Expectancy"], yaxis="y2", name=countries[i], legendgroup=countries[i], showlegend=False)
    for i, df_c in enumerate(data_country)
]
layout = go.Layout(
    title="双坐标轴折线图示例",
    xaxis_title="年",
    yaxis=dict(title="Spending_USD"),
    yaxis2=dict(title="Life_Expectancy", overlaying="y", side="right"),  # 使用overlaying属性将第二个Y轴叠加在第一个Y轴上,并设置在右侧
    legend=dict(yanchor="middle", y=0.5, xanchor="left", x=1.1, title=dict(text="Country")),  # 右侧垂直居中
)

fig = go.Figure(data=traces, layout=layout)  # 创建图表对象
pio.write_image(fig, "../../charts/line-go.png")

 

import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd
import plotly.io as pio

fig = make_subplots(specs=[[{"secondary_y": True}]])
df = pd.read_csv("../../seaborn-data-master/healthexp.csv")
countries = df["Country"].unique()
data_country = [df.query(f"Country=='{c}'") for c in countries]
for country, df_c in zip(countries, data_country):
    fig.add_trace(
        go.Scatter(
            x=df_c["Year"],
            y=df_c["Spending_USD"],
            name=country,
            legendgroup=country,
            mode="lines+markers",
        ),
        secondary_y=False,
    )
    fig.add_trace(
        go.Scatter(
            x=df_c["Year"],
            y=df_c["Life_Expectancy"],
            name=country,
            legendgroup=country,
            showlegend=False,
            mode="lines+markers",
        ),
        secondary_y=True,
    )
fig.update_layout(
    title="双坐标轴折线图示例",
    legend_title_text="国家",
    xaxis_title="年",
)  # 更新布局
fig.update_yaxes(title_text="Spending_USD", secondary_y=False)  # 设置坐标轴标签
fig.update_yaxes(title_text="Life_Expectancy", secondary_y=True)
pio.write_image(fig, "../../charts/line-go-1.png")

 柱状图

import plotly.express as px
import pandas as pd
import plotly.io as pio

# 柱状图
df = pd.read_csv("../../seaborn-data-master/healthexp.csv")
df_y = df.groupby("Year", as_index=False)[["Life_Expectancy"]].mean()
fig = px.bar(df_y, x="Year", y="Life_Expectancy", title="柱状图")
fig.update_yaxes(range=[65, 85])  # 设置 Y 轴范围
pio.write_image(fig, "../../charts/bar-px.png")


# 水平柱状图
df_c = df.groupby("Country", as_index=False)[["Life_Expectancy"]].mean()
df_c = df_c.sort_values("Life_Expectancy", ascending=False)
fig = px.bar(df_c, x="Life_Expectancy", y="Country", title="水平柱状图", orientation="h")
fig.update_yaxes(autorange="reversed")  # 反转 Y 轴顺序
fig.update_xaxes(range=[65, 85])  # 设置 Y 轴范围
fig.update_layout(margin=dict(l=50))  # 增加左侧边距
pio.write_image(fig, "../../charts/bar-h-px.png")


# 分组柱状图:barmode='group'
fig = px.bar(df[-18:], x="Year", y="Life_Expectancy", color="Country", barmode="group", title="分组柱状图", text="Life_Expectancy")
fig.update_yaxes(range=[65, 85])  # 设置 Y 轴范围
pio.write_image(fig, "../../charts/bar-group-px.png", scale=2)

 柱状图

水平柱状图

 分组柱状图

graph_objects接口

import plotly.graph_objects as go
import pandas as pd
import plotly.io as pio

# 分组柱状图
df = pd.read_csv("../../seaborn-data-master/healthexp.csv")
countries = df["Country"].unique()
df_country = [df.query(f"Country=='{c}'").tail(3) for c in countries]
traces = [
    go.Bar(x=df_c["Year"], y=df_c["Life_Expectancy"], name=countries[i], text=df_c["Life_Expectancy"], textposition="auto")
    for i, df_c in enumerate(df_country)
]  # 创建分组柱状图并添加数据标签
layout = go.Layout(
    barmode="group",
    title="分组-平均寿命",
    xaxis_title="年",
    yaxis=dict(title="Life_Expectancy"),
    legend_title_text="Country",
    bargap=0.2,  # 修改分组间距
    bargroupgap=0.1,  # 修改组内柱状间距
)
fig = go.Figure(data=traces, layout=layout)  # 创建图表对象
pio.write_image(fig, "../../charts/bar-group-go.png", scale=2)


# 堆积柱状图
df = pd.read_csv("../../seaborn-data-master/tips.csv")
df = df.groupby(["day", "time"], as_index=False)[["tip"]].mean()  # 统计
times = df["time"].unique()
df_times = [df.query(f"time=='{t}'").drop(["time"], axis=1) for t in times]
fig = go.Figure()
for t, df_t in zip(times, df_times):
    fig.add_trace(go.Bar(x=df_t["day"], y=df_t["tip"], name=t, text=df_t["tip"]))
fig.update_layout(
    barmode="stack",
    title="堆积柱状图",
    xaxis_title="time",
    yaxis_title="tip",
)
pio.write_image(fig, "../../charts/bar-stack-go.png", scale=2)


# 百分比堆积柱状图
df_times_total = pd.DataFrame()
days = df["day"].unique()
total = {day: 0 for day in days}
for i, df_t in enumerate(df_times):
    for row in df_t.itertuples():  # 行遍历dataframe
        total[row.day] = total[row.day] + row.tip  # 计算总数
    df_times[i] = df_t.set_index("day")
df_times_total = pd.DataFrame(
    {
        "day": list(total.keys()),
        "total": list(total.values()),
    }
)
df_times_total = df_times_total.set_index("day")
for i, df_t in enumerate(df_times):
    df_times[i]["percent"] = df_t["tip"] / df_times_total["total"]  # 计算百分比
fig = go.Figure()
for t, df_t in zip(times, df_times):
    fig.add_trace(go.Bar(x=df_t.index.tolist(), y=df_t["percent"], name=t, text=[f"{p*100:.1f}%" for p in df_t["percent"]], textposition="inside"))
fig.update_layout(
    barmode="stack",
    title="百分比堆积柱状图",
    xaxis_title="time",
    yaxis_title="tip-百分比",
    yaxis=dict(tickformat=".0%"),  # 设置y轴刻度格式为百分比
    legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1),
)
pio.write_image(fig, "../../charts/bar-stack-p-go.png", scale=2)

 堆积柱状图

百分比堆积柱状图

饼图

import plotly.express as px
import pandas as pd
import plotly.io as pio

# 饼图
df = pd.read_csv("../../seaborn-data-master/tips.csv")
df_day = df.groupby("day", as_index=False)[["total_bill", "tip"]].mean()
fig = px.pie(df_day, names="day", values="total_bill", title="饼图", hole=0.2)
pio.write_image(fig, "../../charts/pie-px.png")

 

 graph_objects接口

import plotly.graph_objects as go
import pandas as pd
import plotly.io as pio

# 饼图
df = pd.read_csv("../../seaborn-data-master/tips.csv")
df_day = df.groupby("day", as_index=False)[["total_bill", "tip"]].mean()
# pull:特定切片高亮
# text:标签
# marker:样式
traces = [
    go.Pie(
        labels=df_day["day"],
        values=df_day["total_bill"],
        text=df_day["day"],
        textposition="outside",
        hole=0.2,
        pull=[0, 0.1, 0, 0],
        marker=dict(line=dict(color="white", width=5)),
    )
]
# paper_bgcolor:图表背景色配置
layout = go.Layout(title="饼图", paper_bgcolor="lightgray")
fig = go.Figure(data=traces, layout=layout)
pio.write_image(fig, "../../charts/pie-go.png")

 

箱型图

import plotly.express as px
import pandas as pd
import plotly.io as pio


df = pd.read_csv("../../seaborn-data-master/tips.csv")
# 箱型图
fig = px.box(df, x="day", y="total_bill")
pio.write_image(fig, "../../charts/box-px.png")

# 箱型图带全部数据点
fig = px.box(df, x="day", y="total_bill", points="all")
pio.write_image(fig, "../../charts/box-points-px.png")

# 分组箱型图
fig = px.box(df, x="day", y="total_bill", color="time", boxmode="group")  # 分组显示,默认
pio.write_image(fig, "../../charts/box-group-px.png")
fig = px.box(df, x="day", y="total_bill", color="time", boxmode="overlay")  # 重叠
pio.write_image(fig, "../../charts/box-group-overlay-px.png")

箱型图

 

箱型图带全部数据点
分组箱型图

直方图 

import plotly.express as px
import pandas as pd
import plotly.io as pio


df = pd.read_csv("../../seaborn-data-master/tips.csv")
# 直方图
fig = px.histogram(df, x="tip")
pio.write_image(fig, "../../charts/hist-px.png")

# 分组直方图
fig = px.histogram(df, x="tip", color="time", histnorm="probability", barmode="group")
pio.write_image(fig, "../../charts/hist-group-px.png")
fig = px.histogram(df, x="tip", color="time", histnorm="probability", barmode="overlay")
fig.update_layout(bargap=0.2, bargroupgap=0.1)
pio.write_image(fig, "../../charts/hist-group-overlay-px.png")

 

分组直方图

子图布局

import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd
import plotly.io as pio

df = pd.read_csv("../../seaborn-data-master/tips.csv")
df_thur = df.query('day=="Thur"')
df_fri = df.query('day=="Fri"')

# 多子图
fig = make_subplots(rows=2, cols=1, subplot_titles=("Thur", "Fri"))  # 创建子图布局
fig.add_trace(go.Scatter(x=df_thur["total_bill"], y=df_thur["tip"], mode="markers", name="Thur"), row=1, col=1)
fig.add_trace(go.Scatter(x=df_fri["total_bill"], y=df_fri["tip"], mode="markers", name="Fri"), row=2, col=1)
fig.update_layout(height=600, width=600, title_text="tips")
pio.write_image(fig, "../../charts/subplot-go.png")


# 多子图共享坐标轴
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, subplot_titles=("Thur", "Fri"))  # 创建子图布局
fig.add_trace(go.Scatter(x=df_thur["total_bill"], y=df_thur["tip"], mode="markers", name="Thur"), row=1, col=1)
fig.add_trace(go.Scatter(x=df_fri["total_bill"], y=df_fri["tip"], mode="markers", name="Fri"), row=2, col=1)
fig.update_layout(height=600, width=600, title_text="tips")
pio.write_image(fig, "../../charts/subplot-sx-go.png")

express接口
import plotly.express as px
from plotly.subplots import make_subplots
import pandas as pd
import plotly.io as pio

tips = pd.read_csv("../../seaborn-data-master/tips.csv")
fig = make_subplots(rows=2, cols=1, subplot_titles=("day", "time"))  # 创建子图布局
fig1 = px.scatter(tips, x="total_bill", y="tip", color="day")
for i in range(len(fig1.data)):
    fig.add_trace(fig1.data[i], row=1, col=1)
fig2 = px.scatter(tips, x="total_bill", y="tip", color="time")
for i in range(len(fig2.data)):
    fig.add_trace(fig2.data[i], row=2, col=1)
fig.update_layout(height=600, width=600, title_text="tips")  # 更新布局
pio.write_image(fig, "../../charts/subplot-px.png")

 

 模板

import plotly.express as px
import pandas as pd
import plotly.io as pio

tips = pd.read_csv("../../seaborn-data-master/tips.csv")
fig = px.scatter(tips, x="total_bill", y="tip")  # 散点图
pio.write_image(fig, "../../charts/template-default.png")

fig = px.scatter(tips, x="total_bill", y="tip", template="ggplot2")
pio.write_image(fig, "../../charts/template-ggplot2.png")

fig = px.scatter(tips, x="total_bill", y="tip", template="seaborn")
pio.write_image(fig, "../../charts/template-seaborn.png")

fig = px.scatter(tips, x="total_bill", y="tip", template="plotly_dark")
pio.write_image(fig, "../../charts/template-plotly_dark.png")

默认:

ggplot2
seaborn
plotly_dark
posted @ 2025-06-30 11:50  carol2014  阅读(68)  评论(0)    收藏  举报