添加水平、竖直线和填充区域
import plotly.io as pio
import plotly.express as px
import plotly.graph_objects as go
import plotly
from plotly.subplots import make_subplots
import pandas as pd
import numpy as np
# 设置plotly默认主题
pio.templates.default = 'plotly_white'
# 设置pandas打印时显示所有列
pd.set_option('display.max_columns', None)
add_shape / update_shapes 相关参数
官方API:https://plotly.com/python/reference/layout/shapes/
官方示例:https://plotly.com/python/shapes/
- type:指定要绘画shape的类型。如果为 “line”,则绘画一条起点为
(
x
0
,
y
0
)
(x0, y0)
(x0,y0),终点为
(
x
1
,
y
1
)
(x1, y1)
(x1,y1) 的直线;如果为 “circle”,则绘画一个圆心为
(
x
0
+
x
1
2
,
y
0
+
y
1
2
)
(\frac{x0+x1}{2}, \frac{y0+y1}{2})
(2x0+x1,2y0+y1) ,半径为
(
∣
x
0
+
x
1
2
−
x
0
∣
,
∣
y
0
+
y
1
2
−
y
0
∣
)
(|\frac{x0+x1}{2} - x0|, |\frac{y0+y1}{2}-y0|)
(∣2x0+x1−x0∣,∣2y0+y1−y0∣) 的椭圆;如果为 “rect”,则绘制一个依次连接
(
x
0
,
y
0
)
(x0, y0)
(x0,y0)、
(
x
1
,
y
0
)
(x1, y0)
(x1,y0)、
(
x
1
,
y
1
)
(x1, y1)
(x1,y1)、
(
x
0
,
y
1
)
(x0, y1)
(x0,y1)、
(
x
0
,
y
0
)
(x0, y0)
(x0,y0) 的矩形;如果为 “path”,则绘制一个自定义的 SVG 路径,由
path
参数指定。- 字符串枚举类型。可取
"line"
、"circle"
、"rect"
、"path"
- 字符串枚举类型。可取
- x0:设置shape的开始 x 位置
- x1:设置shape的结束 x 位置
- y0:设置shape的开始 y 位置
- y1:设置shape的结束 y 位置
- xsizemode:设置shape相对于 x 轴的大小尺寸模式。如果设为 “scaled”,那么
x0
、x1
和path
中的x坐标指的是 x 轴上的具体数据值 或者 是绘图区域的宽度比例(如果xref
设为 “paper”);如果设为 “pixel”,xanchor
指定了数据(data)或绘制分数(plot fraction)的 x 位置,但是x0
、x1
和path
中的x坐标 是相对于xanchor
的像素,这样,shape可以有一个固定的宽度,同时保持一个相对于数据(data)或绘制分数(plot fraction)的位置。- 字符串枚举类型,可取
"scaled"
(默认值)、"pixel"
- 字符串枚举类型,可取
- xref:设置shape的 x 坐标轴。如果设置为一个x轴id(例如:“x” 或 “x2”),那么
x
参数将代表对这个坐标轴的操作。如果设置为 “paper”,那么x
参数代表整个绘画区域的绝对坐标,即 0(1)表示左侧(右侧)。如果在 x轴id后面加上 “domain”(空格分隔,如 “x2 domain”),那么其与 “paper” 的效果类似,但是以该轴的长度为基准,不再以整个绘画区域为基准,因此此时的相对坐标,相对的是这个轴,而不是整个绘画区域,例如:“x2 domain” 指的是第二个x轴的值域,此时参数x=0.5
表示第二个x轴值域的中间点。- 可以取
paper
,或者满足正则表达式^x([2-9]|[1-9][0-9]+)?( domain)?$
的字符串
- 可以取
- xanchor:只有当
xsizemode="pixel"
时有效。指定x0
、x1
和path
中的x坐标 相对于 x 轴的锚点。例如:将一个像素大小的shape添加到一个特定的数据值很有用的。 - ysizemode:同 xsizemode
- yref:同 xref
- yanchor:同 xanchor
- path:SVG路径,详见官网
- visible:是否显示该shape,布尔类型
- opacity:设置shape的透明度,[0, 1] 之间的浮点数,默认值为1
- layer:设置shape是绘画在traces的上面,还是下面。
- 字符串枚举类型,可取
"below"
、"above"
(默认值)
- 字符串枚举类型,可取
- fillcolor:设置填充shape内部的颜色,只有当shape为封闭图形时有意义。默认值为:“rgba(0,0,0,0)”
- fillrule:确定复杂路径的哪些区域构成内部。详见:https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule
- 字符串枚举类型,可取
"evenodd"
(默认值)、"nonzero"
- 字符串枚举类型,可取
- line:直线样式设置。字典类型,可取属性如下:
- color:直线的颜色
- dash:直线的样式
- 可取样式字符串
'solid'
(默认值)、'dot'
、'dash'
、'longdash'
、'dashdot'
、'longdashdot'
或一个字符串长度列表,例如:“5px,10px,2px,2px”,即:绘画5px的短线,空10px,画2px短线,空2px
- 可取样式字符串
- width:设置线条宽度
- 大于等于0的整数,默认值为2
- editable:设置shape是否可以被激活编辑。布尔类型
# 使用 Scatter 函数中的 fill 参数绘制填充区域
fig = go.Figure(go.Scatter(x=[0,1,2,0], y=[0,2,0,0], fill="toself"))
fig.write_image('../pic/shape_1.png')
fig.show()
# 在输入值中添加 None,可以分隔多个填充区域
fig = go.Figure(
go.Scatter(
x=[0,1,2,0,None,3,3,5,5,3],
y=[0,2,0,0,None,0.5,1.5,1.5,0.5,0.5],
fill="toself"
)
)
fig.write_image('../pic/shape_2.png')
fig.show()
fig = go.Figure()
# Create scatter trace of text labels
fig.add_trace(go.Scatter(
x=[2, 3.5, 6],
y=[1, 1.5, 1],
text=["Vertical Line",
"Horizontal Dashed Line",
"Diagonal dotted Line"],
mode="text",
))
# Set axes ranges
fig.update_xaxes(range=[0, 7])
fig.update_yaxes(range=[0, 2.5])
# Add shapes
fig.add_shape(type="line",
x0=1, y0=0, x1=1, y1=2,
line=dict(color="RoyalBlue",width=3)
)
fig.add_shape(type="line",
x0=2, y0=2, x1=5, y1=2,
line=dict(
color="LightSeaGreen",
width=4,
dash="dashdot",
)
)
fig.add_shape(type="line",
x0=4, y0=0, x1=6, y1=2,
line=dict(
color="MediumPurple",
width=4,
dash="dot",
)
)
fig.update_shapes(dict(xref='x', yref='y'))
fig.write_image('../pic/shape_3.png')
fig.show()
fig = go.Figure()
# Create scatter trace of text labels
fig.add_trace(go.Scatter(
x=[2, 6], y=[1, 1],
text=["Line positioned relative to the plot",
"Line positioned relative to the axes"],
mode="text",
))
# Set axes ranges
fig.update_xaxes(range=[0, 8])
fig.update_yaxes(range=[0, 2])
fig.add_shape(type="line",
xref="x", yref="y",
x0=4, y0=0, x1=8, y1=1, # 相对坐标
line=dict(
color="LightSeaGreen",
width=3,
),
)
fig.add_shape(type="line",
xref="paper", yref="paper", # 也可以用 x domain 和 y domain
x0=0, y0=0, x1=0.5, y1=0.5, # 绝对坐标
line=dict(
color="DarkOrange",
width=3,
),
)
fig.write_image('../pic/shape_4.png')
fig.show()
fig = go.Figure()
fig.add_trace(go.Scatter(
x=[1.5, 4.5],
y=[0.75, 0.75],
text=["Unfilled Rectangle", "Filled Rectangle"],
mode="text",
))
# Set axes properties
fig.update_xaxes(range=[0, 7], showgrid=False)
fig.update_yaxes(range=[0, 3.5])
# Add shapes
fig.add_shape(type="rect",
x0=1, y0=1, x1=2, y1=3,
line=dict(color="RoyalBlue"),
)
fig.add_shape(type="rect",
x0=3, y0=1, x1=6, y1=2,
line=dict(
color="RoyalBlue",
width=2,
),
fillcolor="LightSkyBlue", # 可以使用 rgba 形式的颜色格式设置填充颜色透明度
)
fig.update_shapes(dict(xref='x', yref='y'))
fig.write_image('../pic/shape_5.png')
fig.show()
fig = go.Figure()
# Create scatter trace of text labels
fig.add_trace(go.Scatter(
x=[1.5, 3.5],
y=[0.75, 2.5],
text=["Unfilled Circle",
"Filled Circle"],
mode="text",
))
# Set axes properties
fig.update_xaxes(range=[0, 4.5], zeroline=False)
fig.update_yaxes(range=[0, 4.5])
# Add circles
fig.add_shape(type="circle",
xref="x", yref="y",
x0=1, y0=1, x1=3, y1=3,
line_color="LightSeaGreen",
)
fig.add_shape(type="circle",
xref="x", yref="y",
fillcolor="PaleTurquoise",
x0=3, y0=3, x1=4, y1=4,
line_color="LightSeaGreen",
)
# Set figure size
fig.update_layout(width=800, height=800)
fig.write_image('../pic/shape_6.png')
fig.show()
np.random.seed(1)
# Generate data
x0 = np.random.normal(2, 0.45, 300)
y0 = np.random.normal(2, 0.45, 300)
x1 = np.random.normal(6, 0.4, 200)
y1 = np.random.normal(6, 0.4, 200)
# Create figure
fig = go.Figure()
# Add scatter traces
fig.add_trace(go.Scatter(x=x0, y=y0, mode="markers"))
fig.add_trace(go.Scatter(x=x1, y=y1, mode="markers"))
# Add shapes
fig.add_shape(type="circle",
xref="x", yref="y",
x0=min(x0), y0=min(y0),
x1=max(x0), y1=max(y0),
opacity=0.2,
fillcolor="blue",
line_color="blue",
)
fig.add_shape(type="circle",
xref="x", yref="y",
x0=min(x1), y0=min(y1),
x1=max(x1), y1=max(y1),
opacity=0.2,
fillcolor="orange",
line_color="orange",
)
# Hide legend
fig.update_layout(showlegend=False)
fig.write_image('../pic/shape_7.png')
fig.show()
fig = go.Figure()
# Create scatter trace of text labels
fig.add_trace(go.Scatter(
x=[1, 1.75, 2.5],
y=[1, 1, 1],
text=["$A$", "$A+B$", "$B$"],
mode="text",
textfont=dict(
color="black",
size=18,
family="Arail",
)
))
# Update axes properties
fig.update_xaxes(
showticklabels=False,
showgrid=False,
zeroline=False,
)
fig.update_yaxes(
showticklabels=False,
showgrid=False,
zeroline=False,
)
# Add circles
fig.add_shape(type="circle",
line_color="blue", fillcolor="blue",
x0=0, y0=0, x1=2, y1=2
)
fig.add_shape(type="circle",
line_color="gray", fillcolor="gray",
x0=1.5, y0=0, x1=3.5, y1=2
)
fig.update_shapes(opacity=0.3, xref="x", yref="y")
fig.update_layout(
margin=dict(l=20, r=20, b=100),
height=600, width=800,
plot_bgcolor="white"
)
fig.write_image('../pic/shape_8.png')
fig.show()
# Create Subplots
fig = make_subplots(rows=2, cols=2)
fig.add_trace(go.Scatter(x=[2, 6], y=[1,1]), row=1, col=1)
fig.add_trace(go.Bar(x=[1,2,3], y=[4,5,6]), row=1, col=2)
fig.add_trace(go.Scatter(x=[10,20], y=[40,50]), row=2, col=1)
fig.add_trace(go.Bar(x=[11,13,15], y=[8,11,20]), row=2, col=2)
# Add shapes
fig.update_layout(
shapes=[
dict(type="line", xref="x", yref="y",
x0=3, y0=0.5, x1=5, y1=0.8, line_width=3),
dict(type="rect", xref="x2", yref='y2',
x0=4, y0=2, x1=5, y1=6),
dict(type="rect", xref="x3", yref="y3",
x0=10, y0=20, x1=15, y1=30),
dict(type="circle", xref="x4", yref="y4",
x0=5, y0=12, x1=10, y1=18)
]
)
fig.write_image('../pic/shape_9.png')
fig.show()
df = px.data.tips()
fig = px.scatter(df, x="total_bill", y="tip", facet_row="smoker", facet_col="sex")
# Adds a rectangle to all facets
fig.add_shape(
dict(type="rect", x0=25, x1=35, y0=4, y1=6, line_color="purple"),
row="all",
col="all",
)
# Adds a line to all the rows of the second column
fig.add_shape(
dict(type="line", x0=20, x1=25, y0=5, y1=6, line_color="yellow"), row="all", col=2
)
# Adds a circle to all the columns of the first row
fig.add_shape(
dict(type="circle", x0=10, y0=2, x1=20, y1=7), row=1, col="all", line_color="green"
)
fig.write_image('../pic/shape_10.png')
fig.show()
# SVG path
fig = go.Figure()
# Create scatter trace of text labels
fig.add_trace(go.Scatter(
x=[2, 1, 8, 8],
y=[0.25, 9, 2, 6],
text=["Filled Triangle",
"Filled Polygon",
"Quadratic Bezier Curves",
"Cubic Bezier Curves"],
mode="text",
))
# Update axes properties
fig.update_xaxes(
range=[0, 9],
zeroline=False,
)
fig.update_yaxes(
range=[0, 11],
zeroline=False,
)
# Add shapes
fig.update_layout(
shapes=[
# Quadratic Bezier Curves
dict(
type="path",
path="M 4,4 Q 6,0 8,4",
line_color="RoyalBlue",
),
# Cubic Bezier Curves
dict(
type="path",
path="M 1,4 C 2,8 6,4 8,8",
line_color="MediumPurple",
),
# filled Triangle
dict(
type="path",
path=" M 1 1 L 1 3 L 4 1 Z",
fillcolor="LightPink",
line_color="Crimson",
),
# filled Polygon
dict(
type="path",
path=" M 3,7 L2,8 L2,9 L3,10, L4,10 L5,9 L5,8 L4,7 Z",
fillcolor="PaleTurquoise",
line_color="LightSeaGreen",
),
]
)
fig.write_image('../pic/shape_11.png')
fig.show()
add_hline / add_vline 相关参数
官方示例:https://plotly.com/python/horizontal-vertical-shapes/
官方API:https://plotly.com/python-api-reference/generated/plotly.graph_objects.Figure.html?highlight=#plotly.graph_objects.Figure.add_hline
- x:竖直线的x坐标,只有 add_vline 才有
- y:水平线的y坐标,只有 add_hline 才有
- exclude_empty_subplots:不在空子图上绘制,默认为 True
- row:指定绘制的子图行。如果为 “all”,表示所有行都绘制,如果
row
和col
都为None
,则在第一个图上绘制。也可以为指定行的索引,由1开始。 - col:指定绘制的子图列。如果为 “all”,表示所有列都绘制,如果
row
和col
都为None
,则在第一个图上绘制。也可以为指定列的索引,由1开始。 - annotation:设置标注,字典类型,详见添加标注专题
- annotation_position:设置标注的位置,可选择的字符串组合 [“inside”, “outside”] [“top”, “bottom”] [“left”, “right”]。例如:“outside top left”、“inside bottom”、“right”、“inside left”、“inside”(不能单独为 “outside”),默认为 “inside top right”
- annotation_*:任何以 annotation_ 开头的参数
- 其他任何来自于 add_shape 中的参数,除了
x0, x1, y0, y1, type
add_hrect / add_vrect 相关参数
- y0 和 y1:分别代表矩形纵轴的一端坐标,add_hrect 所有
- x0 和 x1:分别代表矩形横轴的一端坐标,**add_vrect **所有
- exclude_empty_subplots:同上
- row 和 col :同上
- annotation:同上
- annotation_position:同上
- annotation_*:同上
- 其他任何来自于 add_shape 中的参数,除了
x0, x1, y0, y1, type
df = px.data.iris()
fig = px.scatter(df, x="petal_length", y="petal_width")
fig.add_hline(y=0.9)
fig.add_vrect(x0=0.9, x1=2)
fig.write_image('../pic/shape_12.png')
fig.show()
df = px.data.iris()
fig = px.scatter(df, x="petal_length", y="petal_width")
fig.add_vline(x=2.5, line_width=3, line_dash="dash", line_color="green")
fig.add_hrect(y0=0.9, y1=2.6, line_width=0, fillcolor="red", opacity=0.2)
fig.write_image('../pic/shape_13.png')
fig.show()
df = px.data.stocks(indexed=True)
fig = px.line(df)
fig.add_hline(y=1, line_dash="dot",
annotation_text="Jan 1, 2018 baseline",
annotation_position="bottom right")
fig.add_vrect(x0="2018-09-24", x1="2018-12-18",
annotation_text="decline", annotation_position="top left",
fillcolor="green", opacity=0.25, line_width=0)
fig.write_image('../pic/shape_14.png')
fig.show()
df = px.data.stocks(indexed=True)
fig = px.line(df)
fig.add_hline(y=1, line_dash="dot",
annotation_text="Jan 1, 2018 baseline",
annotation_position="bottom right",
annotation_font_size=20,
annotation_font_color="blue"
)
fig.add_vrect(x0="2018-09-24", x1="2018-12-18",
annotation_text="decline", annotation_position="top left",
annotation=dict(font_size=20, font_family="Times New Roman"),
fillcolor="green", opacity=0.25, line_width=0)
fig.write_image('../pic/shape_15.png')
fig.show()
df = px.data.stocks(indexed=True)
fig = px.line(df, facet_col="company", facet_col_wrap=2)
fig.add_hline(y=1, line_dash="dot", row=3, col="all",
annotation_text="Jan 1, 2018 baseline",
annotation_position="bottom right")
fig.add_vrect(x0="2018-09-24", x1="2018-12-18", row="all", col=1,
annotation_text="decline", annotation_position="top left",
fillcolor="green", opacity=0.25, line_width=0)
fig.write_image('../pic/shape_16.png')
fig.show()