如何在给定的图上绘制垂直线
- 2024-12-23 08:43:00
- admin 原创
- 65
问题描述:
给定一个以时间表示的信号图,我如何绘制标记相应时间索引的线?
具体来说,给定一个时间索引范围从 0 到 2.6(秒)的信号图,我想绘制垂直红线以指示列表的相应时间索引[0.22058956, 0.33088437, 2.20589566]
。我该怎么做?
解决方案 1:
添加覆盖整个绘图窗口的垂直线的标准方法是,无需指定其实际高度plt.axvline
import matplotlib.pyplot as plt
plt.axvline(x=0.22058956)
plt.axvline(x=0.33088437)
plt.axvline(x=2.20589566)
或者
xcoords = [0.22058956, 0.33088437, 2.20589566]
for xc in xcoords:
plt.axvline(x=xc)
您可以使用其他绘图命令中可用的许多关键字(例如color
,,...)。您可以传入关键字参数linestyle
,如果您愿意,还可以传入轴坐标(例如,将覆盖绘图的中间一半)。水平线( )和矩形( )有相应的函数。linewidth
`yminymax
ymin=0.25ymax=0.75
axhline`axvspan
解决方案 2:
matplotlib.pyplot.vlines
对阵matplotlib.pyplot.axvline
这些方法适用于使用 seaborn 和 生成的图
pandas.DataFrame.plot
,两者都使用matplotlib
。不同之处
vlines
在于 接受 一个或多个位置x
,而axvline
允许一个位置。单一位置:
x=37
。多个位置:
x=[37, 38, 39]
。
vlines
将ymin
和ymax
作为 y 轴上的位置,而axvline
将ymin
和ymax
作为 y 轴范围的百分比。当传递多行到 时
vlines
,将 a 传递list
到ymin
和ymax
。
也
matplotlib.axes.Axes.vlines
适用matplotlib.axes.Axes.axvline
于面向对象的 API。如果您要绘制类似 的图形
fig, ax = plt.subplots()
,则分别将plt.vlines
或替换plt.axvline
为ax.vlines
或ax.axvline
。
请参阅此答案以了解带有的水平线
.hlines
。
import numpy as np
import matplotlib.pyplot as plt
xs = np.linspace(1, 21, 200)
plt.figure(figsize=(10, 7))
# only one line may be specified; full height
plt.axvline(x=36, color='b', label='axvline - full height')
# only one line may be specified; ymin & ymax specified as a percentage of y-range
plt.axvline(x=36.25, ymin=0.05, ymax=0.95, color='b', label='axvline - % of full height')
# multiple lines all full height
plt.vlines(x=[37, 37.25, 37.5], ymin=0, ymax=len(xs), colors='purple', ls='--', lw=2, label='vline_multiple - full height')
# multiple lines with varying ymin and ymax
plt.vlines(x=[38, 38.25, 38.5], ymin=[0, 25, 75], ymax=[200, 175, 150], colors='teal', ls='--', lw=2, label='vline_multiple - partial height')
# single vline with full ymin and ymax
plt.vlines(x=39, ymin=0, ymax=len(xs), colors='green', ls=':', lw=2, label='vline_single - full height')
# single vline with specific ymin and ymax
plt.vlines(x=39.25, ymin=25, ymax=150, colors='green', ls=':', lw=2, label='vline_single - partial height')
# place the legend outside
plt.legend(bbox_to_anchor=(1.0, 1), loc='upper left')
plt.show()
Seaborn轴级图
import seaborn as sns
# sample data
fmri = sns.load_dataset("fmri")
# x index for max y values for stim and cue
c_max, s_max = fmri.pivot_table(index='timepoint', columns='event', values='signal', aggfunc='mean').idxmax()
# plot
g = sns.lineplot(data=fmri, x="timepoint", y="signal", hue="event")
# y min and max
ymin, ymax = g.get_ylim()
# vertical lines
g.vlines(x=[c_max, s_max], ymin=ymin, ymax=ymax, colors=['tab:orange', 'tab:blue'], ls='--', lw=2)
Seaborn图形级绘图
必须对每个轴进行迭代。
import seaborn as sns
# sample data
fmri = sns.load_dataset("fmri")
# used to get the index values (x) for max y for each event in each region
fpt = fmri.pivot_table(index=['region', 'timepoint'], columns='event', values='signal', aggfunc='mean')
# plot
g = sns.relplot(data=fmri, x="timepoint", y="signal", col="region", hue="event", kind="line")
# iterate through the axes
for ax in g.axes.flat:
# get y min and max
ymin, ymax = ax.get_ylim()
# extract the region from the title for use in selecting the index of fpt
region = ax.get_title().split(' = ')[1]
# get x values for max event
c_max, s_max = fpt.loc[region].idxmax()
# add vertical lines
ax.vlines(x=[c_max, s_max], ymin=ymin, ymax=ymax, colors=['tab:orange', 'tab:blue'], ls='--', lw=2, alpha=0.5)
因为
'region = frontal'
两个事件的最大值都发生在5
。
条形图
条形图具有分类独立轴,因此刻度位置具有从零开始的索引,而不管轴刻度标签如何。
x
根据条形索引而不是刻度标签进行选择。ax.get_xticklabels()
将显示位置和标签。
import pandas as pd
import seaborn as sns
# load data
tips = sns.load_dataset('tips')
# histogram
ax = tips.plot(kind='hist', y='total_bill', bins=30, ec='k', title='Histogram with Vertical Line')
_ = ax.vlines(x=16.5, ymin=0, ymax=30, colors='r')
# barplot
ax = tips.loc[5:25, ['total_bill', 'tip']].plot(kind='bar', figsize=(15, 4), title='Barplot with Vertical Lines', rot=0)
_ = ax.vlines(x=[0, 17], ymin=0, ymax=45, colors='r')
直方图
直方图有一个连续独立的轴。
import pandas as pd
import seaborn as sns
# load data
tips = sns.load_dataset('tips')
# histogram from pandas, pyplot, or seaborn
ax = tips.plot(kind='hist', y='total_bill', bins=30, ec='k', title='Histogram with Vertical Line')
_ = ax.vlines(x=16.5, ymin=0, ymax=30, colors='r')
时间序列轴
作为 x 轴的数据框中的日期必须是
datetime dtype
。如果列或索引不是正确的类型,则必须将其转换为pd.to_datetime
。如果使用日期数组或列表,请分别参考将 numpy 字符串数组转换为日期时间 或将日期时间列表转换为日期 python。
x
`'2020-09-24'将接受像或 这样的日期
datetime(2020, 9, 2)`。
import pandas_datareader as web # conda or pip install this; not part of pandas
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
# get test data; this data is downloaded with the Date column in the index as a datetime dtype
df = web.DataReader('^gspc', data_source='yahoo', start='2020-09-01', end='2020-09-28').iloc[:, :2]
# display(df.head(2))
High Low
Date
2020-09-01 3528.030029 3494.600098
2020-09-02 3588.110107 3535.229980
# plot dataframe; the index is a datetime index
ax = df.plot(figsize=(9, 6), title='S&P 500', ylabel='Price')
# add vertical lines
ax.vlines(x=[datetime(2020, 9, 2), '2020-09-24'], ymin=3200, ymax=3600, color='r', label='test lines')
ax.legend(bbox_to_anchor=(1, 1), loc='upper left')
plt.show()
解决方案 3:
对于多行
xposition = [0.3, 0.4, 0.45]
for xc in xposition:
plt.axvline(x=xc, color='k', linestyle='--')
解决方案 4:
要向某些垂直线添加legend
and/or colors
,请使用以下命令:
import matplotlib.pyplot as plt
# x coordinates for the lines
xcoords = [0.1, 0.3, 0.5]
# colors for the lines
colors = ['r','k','b']
for xc,c in zip(xcoords,colors):
plt.axvline(x=xc, label='line at x = {}'.format(xc), c=c)
plt.legend()
plt.show()
结果
解决方案 5:
像其他人建议的那样,循环调用 axvline 是可行的,但它可能不方便,因为
每一行都是一个单独的绘图对象,当有许多行时,这会导致运行非常慢。
当您创建图例时,每一行都有一个新条目,这可能不是您想要的。
相反,您可以使用以下便捷函数将所有线条创建为单个绘图对象:
import matplotlib.pyplot as plt
import numpy as np
def axhlines(ys, ax=None, lims=None, **plot_kwargs):
"""
Draw horizontal lines across plot
:param ys: A scalar, list, or 1D array of vertical offsets
:param ax: The axis (or none to use gca)
:param lims: Optionally the (xmin, xmax) of the lines
:param plot_kwargs: Keyword arguments to be passed to plot
:return: The plot object corresponding to the lines.
"""
if ax is None:
ax = plt.gca()
ys = np.array((ys, ) if np.isscalar(ys) else ys, copy=False)
if lims is None:
lims = ax.get_xlim()
y_points = np.repeat(ys[:, None], repeats=3, axis=1).flatten()
x_points = np.repeat(np.array(lims + (np.nan, ))[None, :], repeats=len(ys), axis=0).flatten()
plot = ax.plot(x_points, y_points, scalex = False, **plot_kwargs)
return plot
def axvlines(xs, ax=None, lims=None, **plot_kwargs):
"""
Draw vertical lines on plot
:param xs: A scalar, list, or 1D array of horizontal offsets
:param ax: The axis (or none to use gca)
:param lims: Optionally the (ymin, ymax) of the lines
:param plot_kwargs: Keyword arguments to be passed to plot
:return: The plot object corresponding to the lines.
"""
if ax is None:
ax = plt.gca()
xs = np.array((xs, ) if np.isscalar(xs) else xs, copy=False)
if lims is None:
lims = ax.get_ylim()
x_points = np.repeat(xs[:, None], repeats=3, axis=1).flatten()
y_points = np.repeat(np.array(lims + (np.nan, ))[None, :], repeats=len(xs), axis=0).flatten()
plot = ax.plot(x_points, y_points, scaley = False, **plot_kwargs)
return plot
解决方案 6:
除了上述答案中提供的plt.axvline
andplt.plot((x1, x2), (y1, y2))
或之外,还可以使用 plt.plot([x1, x2], [y1, y2])
plt.vlines(x_pos, ymin=y1, ymax=y2)
在 到 处绘制一条垂直线,其中值和以绝对数据坐标x_pos
表示。y1
`y2y1
y2`
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理必备:盘点2024年13款好用的项目管理软件