Given a plot of a signal in time representation, how can I draw lines marking the corresponding time index?
Specifically, given a signal plot with a time index ranging from 0 to 2.6 (seconds), I want to draw vertical red lines indicating the corresponding time index for the list [0.22058956, 0.33088437, 2.20589566]
. How can I do it?
By using axvline() In matplotlib, the axvline() method is used to add vertical lines to the plot. The above-used parameters are described as below: x: specify position on the x-axis to plot the line. ymin and ymax: specify the starting and ending range of the line.
The method axhline and axvline are used to draw lines at the axes coordinate. In this coordinate system, coordinate for the bottom left point is (0,0), while the coordinate for the top right point is (1,1), regardless of the data range of your plot. Both the parameter xmin and xmax are in the range [0,1].
The standard way to add vertical lines that will cover your entire plot window without you having to specify their actual height is plt.axvline
import matplotlib.pyplot as plt
plt.axvline(x=0.22058956)
plt.axvline(x=0.33088437)
plt.axvline(x=2.20589566)
OR
xcoords = [0.22058956, 0.33088437, 2.20589566]
for xc in xcoords:
plt.axvline(x=xc)
You can use many of the keywords available for other plot commands (e.g. color
, linestyle
, linewidth
...). You can pass in keyword arguments ymin
and ymax
if you like in axes corrdinates (e.g. ymin=0.25
, ymax=0.75
will cover the middle half of the plot). There are corresponding functions for horizontal lines (axhline
) and rectangles (axvspan
).
matplotlib.pyplot.vlines
vs. matplotlib.pyplot.axvline
pandas.DataFrame.plot
, which both use matplotlib
.vlines
accepts one or more locations for x
, while axvline
permits one location.
x=37
.x=[37, 38, 39]
.vlines
takes ymin
and ymax
as a position on the y-axis, while axvline
takes ymin
and ymax
as a percentage of the y-axis range.
vlines
, pass a list
to ymin
and ymax
.matplotlib.axes.Axes.vlines
and matplotlib.axes.Axes.axvline
for the object-oriented API.
fig, ax = plt.subplots()
, then replace plt.vlines
or plt.axvline
with ax.vlines
or ax.axvline
, respectively..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()
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)
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'
the maximum value of both events occurs at 5
.x
based on the bar index, not the tick label.
ax.get_xticklabels()
will show the locations and labels.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')
datetime dtype
. If the column or index is not the correct type, it must be converted with pd.to_datetime
.
x
will accept a date like '2020-09-24'
or 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()
For multiple lines
xposition = [0.3, 0.4, 0.45]
for xc in xposition:
plt.axvline(x=xc, color='k', linestyle='--')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With