文章目录
Plotly.py 中的散点图和折线图
用 Plotly Express 绘制散点图
Plotly Express 是一种易于使用的高阶 Plotly 接口,它提供了面向各种数据形式的操作方法,可以用来生成方便个性化的图表。
使用 px.scatter
,所有的数据点都会视为一个标记点,它们的坐标由给定的 x
和 y
数据列定义。
提示:
我们假设以下部分的 Python 源代码是在一个 Jupyter Notebook 环境中从上至下运行的,对于一些
import
导入命令,我们不再进行重复导入。同时,由于 Jupyter Notebook 无法将 Plotly.py 生成的图表进行导出,此处不提供图表可视化效果。
from plotly import express as px
# x 和 y 是列表形式的对象
fig = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16])
fig.show()
import plotly.express as px
# 这是一个 pandas.DataFrame 数据集
df = px.data.iris()
fig = px.scatter(df, x="sepal_width", y="sepal_length")
fig.show()
提示:
这也解释了为什么 Plotly 需要 pandas 作为前置依赖的原因~
根据特定列指定大小和颜色
具有可变圆形散点大小的散点图也被称为 气泡图 。请注意,color
和 size
数据会被添加到悬浮信息栏中,你可以借助 px.scatter
的 hover_data
参数将其他数据列添加到悬浮信息栏。
fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species",
size='petal_length', hover_data=['petal_width'])
fig.show()
色彩既可以像下面这样是连续的,也可以像上面那样是离散/类别值。
fig = px.scatter(df, x="sepal_width", y="sepal_length", color='petal_length')
fig.show()
symbol
参数也可以和数据列建立映射,有 一大堆的标记样式 可以使用。
fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species", symbol="species")
fig.show()
散点图与离散坐标轴
散点图可以在任意的笛卡尔坐标系下绘制,包括 常规坐标系 、对数坐标系 、类别坐标系 和 时间坐标系 。
当散点图的其中一个坐标轴是类别值时,这种图一般被额外叫做 点状图 。
df = px.data.medals_long()
fig = px.scatter(df, y="nation", x="count", color="medal", symbol="medal")
fig.update_traces(marker_size=10)
fig.show()
误差柱
散点图支持为每一个数据点添加 误差柱 。
df = px.data.iris()
df["e"] = df["sepal_width"]/100
fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species",
error_x="e", error_y="e")
fig.show()
边际分布图
散点图支持添加 边际分布图 。
fig = px.scatter(df, x="sepal_length", y="sepal_width",
marginal_x="histogram", marginal_y="rug")
fig.show()
分面
散点图支持进行 分面 。
df = px.data.tips()
fig = px.scatter(df, x="total_bill", y="tip", color="smoker",
facet_col="sex", facet_row="time")
fig.show()
线性回归或其他趋势线
散点图支持 线性或非线性趋势线 。
# 其中的 OLS 表示线性回归使用的『最小二乘法』
fig = px.scatter(df, x="total_bill", y="tip", trendline="ols")
fig.show()
使用 Plotly Express 绘制曲线图
import numpy as np
t = np.linspace(0, 2*np.pi, 100)
fig = px.line(x=t, y=np.cos(t), labels={'x':'t', 'y':'cos(t)'})
fig.show()
# 这也是一个 pandas.DataFrame 数据集
df = (px.data.gapminder()
# 根据给定的布尔表达式字符串查询数据
# 类似于 SQL 中的 WHERE 关键字
.query("continent == 'Oceania'"))
fig = px.line(df, x='year', y='lifeExp', color='country')
fig.show()
提示:
pandas.DataFrame.query
方法的具体用法可以查阅 Pandas 文档 。
将 markers
参数设置为 True
可以在曲线上显示标记点。
fig = px.line(df, x='year', y='lifeExp', color='country', markers=True)
fig.show()
与散点图相同,带标记的曲线图也支持各式各样的标记样式。
fig = px.line(df, x='year', y='lifeExp', color='country', symbol="country")
fig.show()
时间坐标系上的曲线图
与散点图相同,曲线图也支持在包括线性坐标系、对数坐标系、类别坐标系和时间坐标系在内的笛卡尔坐标系上绘制。在时间坐标系上绘制的曲线图一般也被称为 时间序列图 。
当指定的数据类型是以下三种之一时,Plotly 会自动地将相应坐标轴类型设置为日期格式:
- ISO 格式的日期字符串
- 以日期格式存储的 Pandas 数据列
- 以日期格式存储的 NumPy 数组
df = px.data.stocks()
fig = px.line(df, x='date', y="GOOG")
fig.show()
散点图和曲线图中的时间顺序
Plotly 曲线图是以『用线段连接的散点图』形式实现的,这说明所有的数据点会以数据集提供的顺序绘制并连接,并不会自动地重新排序。
这种机制让我们能够生成下面这样的图表,也说明我们可能需要在将数据传递给 Plotly 之前显式地进行排序以避免曲线在图表中『反向』移动。
import pandas as pd
df = pd.DataFrame(dict(
x = [1, 3, 2, 4],
y = [1, 2, 3, 4]
))
fig = px.line(df, x="x", y="y", title="Unsorted Input")
fig.show()
df = df.sort_values(by="x")
fig = px.line(df, x="x", y="y", title="Sorted Input")
fig.show()
线段连接式散点图
在一个线段连接式散点图中,两个连续的变量值会被独立绘制,并用一条线段将它们以某种具有意义的顺序连接起来,通常情况下会以时间变量来连接。在下面这张图表的源代码中,我们展示了由一对国家在人均 GDP 和寿命上的『趋势』。
df = px.data.gapminder().query("country in ['Canada', 'Botswana']")
fig = px.line(df, x="lifeExp", y="gdpPercap", color="country", text="year")
fig.update_traces(textposition="bottom right")
fig.show()
用 go.Scatter
绘制散点图和曲线图
如果 Plotly Express 无法提供很好的绘图入口,也可以使用 plotly.graph_objects
中更为通用的 go.Scatter
对象。尽管 plotly.express
提供了 scatter
和 line
两个函数,go.Scatter
却可以用来同时绘制它们两个,取决于 mode
参数的取值。go.Scatter
更多的参数请查阅 参考手册 。
简单散点图
from plotly import graph_objects as go
import numpy as np
N = 1000
t = np.linspace(0, 10, 100)
y = np.sin(t)
fig = go.Figure(data=go.Scatter(x=t, y=y, mode='markers'))
fig.show()
连线散点图
使用 mode
参数在『标记点』、『折线』或『两者』之间选择。关于折线图的更多选项,同样请参考 折线图教程 和 区域填充图教程 。
np.random.seed(1)
N = 100
random_x = np.linspace(0, 1, N)
random_y0 = np.random.randn(N) + 5
random_y1 = np.random.randn(N)
random_y2 = np.random.randn(N) - 5
fig = go.Figure()
fig.add_trace(go.Scatter(
x=random_x, y=random_y0,
mode='markers', name='markers'
))
fig.add_trace(go.Scatter(
x=random_x, y=random_y1,
mode='lines+markers', name='lines+markers'
))
fig.add_trace(go.Scatter(
x=random_x, y=random_y2,
mode='lines', name='lines'
))
fig.show()
气泡散点图
在 气泡图 中,数据集的第三个维度以标记的大小呈现。更多的可视化示例请查阅 气泡图教程 。
fig = go.Figure(data=go.Scatter(
x=[1, 2, 3, 4],
y=[10, 11, 12, 13],
mode='markers',
marker={
'size': [40, 60, 80, 100],
'color': [0, 1, 2, 3]
}
))
fig.show()
个性化散点图
t = np.linspace(0, 10, 100)
fig = go.Figure()
fig.add_trace(go.Scatter(
x=t, y=np.sin(t),
name='sin',
mode='markers',
marker_color='rgba(152, 0, 0, .8)'
))
fig.add_trace(go.Scatter(
x=t, y=np.cos(t), name='cos',
marker_color='rgba(255, 182, 193, .9)'
))
# 我们通常使用 fig.update_trace 为所有的 Trace 设置相关参数
fig.update_traces(mode='markers', marker_line_width=2, marker_size=10)
fig.update_layout(
title='Styled Scatter',
yaxis_zeroline=False,
xaxis_zeroline=False
)
fig.show()
悬浮数据标签
data= pd.read_csv(
"https://raw.githubusercontent.com/plotly/" +
"datasets/master/2014_usa_states.csv"
)
fig = go.Figure(data=go.Scatter(
x=data['Postal'], y=data['Population'], mode='markers',
marker_color=data['Population'], text=data['State']
))
fig.update_layout(title='Population of USA States')
fig.show()
具有色彩维度的散点图
fig = go.Figure(data=go.Scatter(
y = np.random.randn(500),
mode='markers',
marker=dict(
size=16,
color=np.random.randn(500), # 设置色彩为一组数值
colorscale='Viridis', # Plotly 提供的其中一种色彩映射表
showscale=True # 展示色柱
)
))
fig.show()
大型数据集
现在,在 Plotly 中你可以用 Scattergl()
取代 Scatter()
,使用 WebGL 提升运行速度、提高可交互性,甚至还能提升绘制更多数据的能力!
N = 100000
fig = go.Figure(data=go.Scattergl(
x = np.random.randn(N),
y = np.random.randn(N),
mode='markers',
marker=dict(
color=np.random.randn(N),
colorscale='Viridis',
line_width=1
)
))
fig.show()
N = 100000
r = np.random.uniform(0, 1, N)
theta = np.random.uniform(0, 2*np.pi, N)
fig = go.Figure(data=go.Scattergl(
x = r * np.cos(theta), # 非均匀分布
y = r * np.sin(theta), # 借助缩放让更多的数据位于图表中心
mode='markers',
marker=dict(
color=np.random.randn(N),
colorscale='Viridis',
line_width=1
)
))
fig.show()