Wykreśl linię poziomą za pomocą matplotlib


148

Użyłem interpolacji splajnów do wygładzenia szeregu czasowego i chciałbym również dodać poziomą linię do wykresu. Ale wydaje się, że jest problem, który jest poza moimi rękami. Każda pomoc byłaby naprawdę pomocna. Oto co mam:

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

Wydaje się, że problem polega na tym, że używam programu [0,len(xs)]do kreślenia linii poziomej.

Odpowiedzi:


8

Masz rację, myślę, że [0,len(xs)]to cię wyrzuca. Będziesz chciał ponownie użyć oryginalnej zmiennej osi X xsi wykreślić ją z inną tablicą numpy o tej samej długości, w której znajduje się twoja zmienna.

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

Mam nadzieję, że to rozwiąże problem!


20
To działa, ale nie jest szczególnie wydajne, zwłaszcza, że ​​tworzysz potencjalnie bardzo dużą tablicę w zależności od danych. Jeśli zamierzasz to zrobić w ten sposób, mądrzej byłoby mieć dwa punkty danych, jeden na początku i jeden na końcu. Mimo to matplotlib ma już dedykowaną funkcję dla linii poziomych.
— BlivetWidget


35

Jeśli chcesz narysować poziomą linię na osiach, możesz również wypróbować ax.hlines()metodę. Należy określić ypozycję i xmini xmaxw danych współrzędnych (czyli rzeczywiste dane wahają się w osi x). Przykładowy fragment kodu to:

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

Powyższy fragment wykreśli poziomą linię na osiach w y=0.2. Linia pozioma zaczyna się x=4i kończy na x=20. Wygenerowany obraz to:

wprowadź opis obrazu tutaj


jest to o wiele wygodniejsze niż axhlinewtedy, gdy potrzebny jest określony zakres x linii, którą zamierzałeś narysować. Jaka jest różnica między „axhline” a „hlines”?
— Jason Goal

W axhlineprogramie xmini xmaxsą pod względem współrzędnych osi, tak aby znajdowały się w zakresie [0, 1]. Możesz zobaczyć tutaj różnicę między różnymi układami współrzędnych.
— jdhao

Dzięki, jeśli to xmini xmaxróżnica jest jedyną różnicą między axhlinei hlines, czy to drugie nie dominuje nad pierwszym?
— Jason Goal

20

Zastosowanie matplotlib.pyplot.hlines:

  • Można wykreślić wiele linii poziomych, przekazując a listdo yparametru.
  • y można przekazać jako jedną lokalizację: y=40
  • y można przekazać jako wiele lokalizacji: y=[39, 40, 41]
  • Jeśli jesteś kreślenia postać z czymś takim fig, ax = plt.subplots(), czym zastąpić plt.hlinesalbo plt.axhlinez ax.hlinesalbo ax.axhline, odpowiednio.
  • matplotlib.pyplot.axhlinemoże wykreślić tylko jedną lokalizację (np. y=40)

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)

wprowadź opis obrazu tutaj

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

wprowadź opis obrazu tutaj

Oś szeregów czasowych

  • xmini xmaxzaakceptuje datę, taką jak '2020-09-10'lubdatetime(2020, 9, 10)
    • xmin=datetime(2020, 9, 10), xmax=datetime(2020, 9, 10) + timedelta(days=3)
    • Biorąc pod uwagę date = df.index[9], xmin=date, xmax=date + pd.Timedelta(days=3)gdzie indeks to DatetimeIndex.
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
df = web.DataReader('^gspc', data_source='yahoo', start='2020-09-01', end='2020-09-28').iloc[:, :2]

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

wprowadź opis obrazu tutaj

  • Przykładowe dane szeregów czasowych, jeśli web.DataReadernie działają.
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')

12

Oprócz najbardziej upvoted odpowiedzi tutaj, można również łańcuch axhlinepo wywołaniu plotna a pandas„s DataFrame.

import pandas as pd

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

wprowadź opis obrazu tutaj


4

Miły i łatwy sposób dla osób, które zawsze zapominają o poleceniu, axhlinejest następujący

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

W twoim przypadku xs = xi y = 40. Jeśli len (x) jest duże, staje się to nieefektywne i naprawdę powinieneś użyć axhline.


2

Możesz użyć plt.griddo narysowania poziomej linii.

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

przykład losowego wykresu danych

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.