如何将一条水平线添加到现有的绘图中?
当前回答
使用matplotlib.pyplot.hlines:
These methods are applicable to plots generated with seaborn and pandas.DataFrame.plot, which both use matplotlib. Plot multiple horizontal lines by passing a list to the y parameter. y can be passed as a single location: y=40 y can be passed as multiple locations: y=[39, 40, 41] Also matplotlib.axes.Axes.hlines for the object oriented api. If you're a plotting a figure with something like fig, ax = plt.subplots(), then replace plt.hlines or plt.axhline with ax.hlines or ax.axhline, respectively. matplotlib.pyplot.axhline & matplotlib.axes.Axes.axhline can only plot a single location (e.g. y=40) See this answer for vertical lines with .vlines
plt.plot
import numpy as np
import matplotlib.pyplot as plt
xs = np.linspace(1, 21, 200)
plt.figure(figsize=(6, 3))
plt.hlines(y=39.5, xmin=100, xmax=175, colors='aqua', linestyles='-', lw=2, label='Single Short Line')
plt.hlines(y=[39, 40, 41], xmin=[0, 25, 50], xmax=[len(xs)], colors='purple', linestyles='--', lw=2, label='Multiple Lines')
plt.legend(bbox_to_anchor=(1.04,0.5), loc="center left", borderaxespad=0)
ax.plot
import numpy as np
import matplotlib.pyplot as plt
xs = np.linspace(1, 21, 200)
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(6, 6))
ax1.hlines(y=40, xmin=0, xmax=len(xs), colors='r', linestyles='--', lw=2)
ax1.set_title('One Line')
ax2.hlines(y=[39, 40, 41], xmin=0, xmax=len(xs), colors='purple', linestyles='--', lw=2)
ax2.set_title('Multiple Lines')
plt.tight_layout()
plt.show()
海波恩轴水平图
import seaborn as sns
# sample data
fmri = sns.load_dataset("fmri")
# max y values for stim and cue
c_max, s_max = fmri.pivot_table(index='timepoint', columns='event', values='signal', aggfunc='mean').max()
# plot
g = sns.lineplot(data=fmri, x="timepoint", y="signal", hue="event")
# x min and max
xmin, ymax = g.get_xlim()
# vertical lines
g.hlines(y=[c_max, s_max], xmin=xmin, xmax=xmax, colors=['tab:orange', 'tab:blue'], ls='--', lw=2)
Seaborn数字级图
必须遍历每个轴
import seaborn as sns
# sample data
fmri = sns.load_dataset("fmri")
# used to get the max values (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", style="event", kind="line")
# iterate through the axes
for ax in g.axes.flat:
# get x min and max
xmin, xmax = ax.get_xlim()
# 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].max()
# add horizontal lines
ax.hlines(y=[c_max, s_max], xmin=xmin, xmax=xmax, colors=['tab:orange', 'tab:blue'], ls='--', lw=2, alpha=0.5)
时间序列轴
xmin and xmax will accept a date like '2020-09-10' or datetime(2020, 9, 10) Using from datetime import datetime xmin=datetime(2020, 9, 10), xmax=datetime(2020, 9, 10) + timedelta(days=3) Given date = df.index[9], xmin=date, xmax=date + pd.Timedelta(days=3), where the index is a DatetimeIndex. The date column on the axis must be a datetime dtype. If using pandas, then use pd.to_datetime. For an array or list, refer to Converting numpy array of strings to datetime or Convert datetime list into date python, respectively.
import pandas_datareader as web # conda or pip install this; not part of pandas
import pandas as pd
import matplotlib.pyplot as plt
# get test data; the Date index is already downloaded as 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
ax = df.plot(figsize=(9, 6), title='S&P 500', ylabel='Price')
# add horizontal line
ax.hlines(y=3450, xmin='2020-09-10', xmax='2020-09-17', color='purple', label='test')
ax.legend()
plt.show()
样本时间序列数据,如果web。DataReader不能工作。
data = {pd.Timestamp('2020-09-01 00:00:00'): {'High': 3528.03, 'Low': 3494.6}, pd.Timestamp('2020-09-02 00:00:00'): {'High': 3588.11, 'Low': 3535.23}, pd.Timestamp('2020-09-03 00:00:00'): {'High': 3564.85, 'Low': 3427.41}, pd.Timestamp('2020-09-04 00:00:00'): {'High': 3479.15, 'Low': 3349.63}, pd.Timestamp('2020-09-08 00:00:00'): {'High': 3379.97, 'Low': 3329.27}, pd.Timestamp('2020-09-09 00:00:00'): {'High': 3424.77, 'Low': 3366.84}, pd.Timestamp('2020-09-10 00:00:00'): {'High': 3425.55, 'Low': 3329.25}, pd.Timestamp('2020-09-11 00:00:00'): {'High': 3368.95, 'Low': 3310.47}, pd.Timestamp('2020-09-14 00:00:00'): {'High': 3402.93, 'Low': 3363.56}, pd.Timestamp('2020-09-15 00:00:00'): {'High': 3419.48, 'Low': 3389.25}, pd.Timestamp('2020-09-16 00:00:00'): {'High': 3428.92, 'Low': 3384.45}, pd.Timestamp('2020-09-17 00:00:00'): {'High': 3375.17, 'Low': 3328.82}, pd.Timestamp('2020-09-18 00:00:00'): {'High': 3362.27, 'Low': 3292.4}, pd.Timestamp('2020-09-21 00:00:00'): {'High': 3285.57, 'Low': 3229.1}, pd.Timestamp('2020-09-22 00:00:00'): {'High': 3320.31, 'Low': 3270.95}, pd.Timestamp('2020-09-23 00:00:00'): {'High': 3323.35, 'Low': 3232.57}, pd.Timestamp('2020-09-24 00:00:00'): {'High': 3278.7, 'Low': 3209.45}, pd.Timestamp('2020-09-25 00:00:00'): {'High': 3306.88, 'Low': 3228.44}, pd.Timestamp('2020-09-28 00:00:00'): {'High': 3360.74, 'Low': 3332.91}}
df = pd.DataFrame.from_dict(data, 'index')
Barplot和histogram
请注意,条形图的刻度位置有一个从零开始的索引,而不考虑轴刻度标签,因此根据条形图索引而不是刻度标签选择xmin和xmax。 Ax.get_xticklabels()将显示位置和标签。
import pandas as pd
import seaborn as sns # for tips data
# load data
tips = sns.load_dataset('tips')
# histogram
ax = tips.plot(kind='hist', y='total_bill', bins=30, ec='k', title='Histogram with Horizontal Line')
_ = ax.hlines(y=6, xmin=0, xmax=55, 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.hlines(y=6, xmin=3, xmax=15, colors='r')
其他回答
如果想在坐标轴上画一条水平线,也可以尝试ax.hlines()方法。您需要指定y位置以及数据坐标中的xmin和xmax(即x轴上的实际数据范围)。示例代码片段如下:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(1, 21, 200)
y = np.exp(-x)
fig, ax = plt.subplots()
ax.plot(x, y)
ax.hlines(y=0.2, xmin=4, xmax=20, linewidth=2, color='r')
plt.show()
上面的代码片段将在y=0.2处的轴上绘制一条水平线。水平线从x=4开始,到x=20结束。生成的图像为:
对于那些总是忘记命令轴的人来说,下面是一个很好的和简单的方法
plt.plot(x, [y]*len(x))
在这里,xs = x y = 40。 如果len(x)很大,那么这种方法就很低效,你应该使用axhline。
使用axhline(水平轴线)。例如,这是一条y = 0.5处的水平线:
import matplotlib.pyplot as plt
plt.axhline(y=0.5, color='r', linestyle='-')
plt.show()
除了这里被点赞最多的答案外,人们还可以在熊猫的数据框架上调用plot后链接axhline。
import pandas as pd
(pd.DataFrame([1, 2, 3])
.plot(kind='bar', color='orange')
.axhline(y=1.5));
你是对的,我认为[0,len(xs)]把你弄糊涂了。您需要重用原始的x轴变量xs,并将其与另一个具有相同长度的numpy数组绘制在一起。
annual = np.arange(1,21,1)
l = np.array(value_list) # a list with 20 values
spl = UnivariateSpline(annual,l)
xs = np.linspace(1,21,200)
plt.plot(xs,spl(xs),'b')
#####horizontal line
horiz_line_data = np.array([40 for i in xrange(len(xs))])
plt.plot(xs, horiz_line_data, 'r--')
###########plt.plot([0,len(xs)],[40,40],'r--',lw=2)
pylab.ylim([0,200])
plt.show()
希望这能解决问题!
推荐文章
- 将Pandas或Numpy Nan替换为None以用于MysqlDB
- 使用pandas对同一列进行多个聚合
- 使用Python解析HTML
- django MultiValueDictKeyError错误,我如何处理它
- 如何在for循环期间修改列表条目?
- 我如何在Django中创建一个鼻涕虫?
- 没有名为'django.core.urlresolvers'的模块
- 蟒蛇导出环境文件
- Django - makemigrations -未检测到任何更改
- SQLAlchemy:引擎、连接和会话差异
- 在Python Pandas中删除多个列中的所有重复行
- 更改pandas DataFrame中的特定列名
- 将Pandas多索引转换为列
- 熊猫在每组中获得最高的n个记录
- 熊猫数据帧得到每组的第一行