簡體   English   中英

在給定圖上繪制一條水平線

[英]Plot a horizontal line on a given plot

如何在現有繪圖中添加水平線?

使用axhline (水平軸線)。 例如,這會在y = 0.5處繪制一條水平線:

import matplotlib.pyplot as plt
plt.axhline(y=0.5, color='r', linestyle='-')
plt.show()

示例圖

如果你想在坐標軸上畫一條水平線,你也可以試試ax.hlines()方法。 您需要在數據坐標中指定y位置以及xminxmax (即,您在 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結束。 生成的圖像是:

在此處輸入圖像描述

使用matplotlib.pyplot.hlines

  • 這些方法適用於使用seabornpandas.DataFrame.plot生成的圖,它們都使用matplotlib
  • 通過將list傳遞給y參數來繪制多條水平線。
  • y可以作為單個位置傳遞: y=40
  • y可以作為多個位置傳遞: y=[39, 40, 41]
  • 還有matplotlib.axes.Axes.hlines用於面向對象的 api。
    • 如果您使用fig, ax = plt.subplots()類的東西繪制圖形,則分別將plt.hlinesplt.axhline替換為ax.hlinesax.axhline
  • matplotlib.pyplot.axhline & matplotlib.axes.Axes.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)

在此處輸入圖像描述

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

在此處輸入圖像描述

Seaborn 軸水平圖

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)

在此處輸入圖像描述

時間序列軸

  • 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) ,其中索引是DatetimeIndex
  • 軸上的日期列必須是datetime dtype 如果使用 pandas,則使用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()

在此處輸入圖像描述

  • 如果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')

條形圖和直方圖

  • 請注意,無論軸刻度標簽如何,條形圖刻度位置都有一個從零開始的索引,因此請根據條形索引而不是刻度標簽選擇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')

在此處輸入圖像描述

在此處輸入圖像描述

除了這里最受好評的答案外,還可以在pandasDataFrame上調用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()

希望能解決問題!

對於那些總是忘記命令axhline的人來說,一個簡單的方法如下

plt.plot(x, [y]*len(x))

在你的情況下xs = xy = 40 如果 len(x) 很大,那么這將變得低效,您應該真正使用axhline

您可以使用plt.grid繪制水平線。

import numpy as np
from matplotlib import pyplot as plt
from scipy.interpolate import UnivariateSpline
from matplotlib.ticker import LinearLocator

# your data here
annual = np.arange(1,21,1)
l = np.random.random(20)
spl = UnivariateSpline(annual,l)
xs = np.linspace(1,21,200)

# plot your data
plt.plot(xs,spl(xs),'b')

# horizental line?
ax = plt.axes()
# three ticks:
ax.yaxis.set_major_locator(LinearLocator(3))
# plot grids only on y axis on major locations
plt.grid(True, which='major', axis='y')

# show
plt.show()

隨機數據圖示例

我已經使用樣條插值來平滑時間序列,並且還想在圖中添加一條水平線。 但似乎有一個問題超出了我的掌握。 任何幫助都會非常有幫助。 這是我所擁有的:

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

問題似乎與我使用[0,len(xs)]進行水平線繪圖有關。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM