使用matplotlib绘制水平线

Ibe*_*Ibe 104 python matplotlib

我使用样条插值来平滑时间序列,并且还想在图中添加水平线.但似乎有一个问题不在我的掌握之中.任何帮助都会非常有帮助.这是我有的:

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')

plt.plot([0,len(xs)],[40,40],'r--',lw=2)
pylab.ylim([0,200])
plt.show()
Run Code Online (Sandbox Code Playgroud)

问题似乎与我[0,len(xs)]用于水平线绘图有关.

Bli*_*get 354

你正在寻找axhline(水平轴线).例如,下面将给出y = 0.5的水平线.

import matplotlib.pyplot as plt
plt.axhline(y=0.5, color='r', linestyle='-')
plt.show()
Run Code Online (Sandbox Code Playgroud)

  • 文档:[`axhline`](https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.axhline). (12认同)
  • @Ibe:这应该是公认的答案,因为比 chill_turner 的答案更有效 (4认同)

Tre*_*ney 33

使用matplotlib.pyplot.hlines

  • 通过将 a 传递listy参数来绘制多条水平线。
  • y 可以作为单个位置传递: y=40
  • y 可以作为多个位置传递: y=[39, 40, 41]
  • 如果您正在使用类似的内容绘制图形fig, ax = plt.subplots(),则分别将plt.hlines或替换plt.axhlineax.hlinesax.axhline
  • matplotlib.pyplot.axhline只能绘制一个位置(例如y=40
  • 有关垂直线的信息,请参阅此答案.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)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

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()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

时间序列轴

  • xminxmax会接受像一个日期'2020-09-10'datetime(2020, 9, 10)
    • 使用 from datetime import datetime
    • xmin=datetime(2020, 9, 10), xmax=datetime(2020, 9, 10) + timedelta(days=3)
    • 给定date = df.index[9], xmin=date, xmax=date + pd.Timedelta(days=3),其中索引为 a DatetimeIndex
  • 轴上的日期列必须是datetime dtype. 如果使用熊猫,则使用pd.to_datetime. 对于数组或列表,请分别参阅将 numpy 字符串数组转换为日期时间将日期时间列表转换为日期 python
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()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

  • 如果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')
Run Code Online (Sandbox Code Playgroud)

条形图和直方图

  • 请注意,无论轴标签如何,条形图通常都是 0 索引的,因此选择xminxmax基于条形索引,而不是刻度标签。
    • 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')
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

在此处输入图片说明


jdh*_*hao 21

如果要在轴上绘制水平线,也可以尝试使用ax.hlines()方法.您需要指定ax.hlines()现在的位置,并yxmin在数据坐标(即,在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()
Run Code Online (Sandbox Code Playgroud)

上面的代码片段将在轴上绘制一条水平线xmax.水平线从开始到y=0.2结束x=4.生成的图像是:

在此输入图像描述


chi*_*ner 8

你是对的,我认为这[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()
Run Code Online (Sandbox Code Playgroud)

希望能解决问题!

  • 这可行,但它不是特别有效,特别是当你根据数据创建一个可能非常大的数组时.如果你打算这样做,那么拥有两个数据点会更聪明,一个在开头,一个在结尾.matplotlib仍然具有水平线的专用功能. (10认同)

ayo*_*rgo 8

除了最upvoted答案在这里,你也可以使用链axhline打完电话后plotpandasDataFrame

import pandas as pd

(pd.DataFrame([1, 2, 3])
   .plot(kind='bar', color='orange')
   .axhline(y=1.5));
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


Mos*_*teM 5

对于那些总是忘记命令的人来说,一个简单而简单的方法axhline如下

plt.plot(x, [y]*len(x))
Run Code Online (Sandbox Code Playgroud)

在你的情况xs = xy = 40. 如果 len(x) 很大,那么这会变得效率低下,您应该真正使用axhline.