Python/Matplotlib 在折线图中绘制特定日期的垂直线

Python/Matplotlib plot vertical line for specific dates in line chart

我用 pandas 读取了特斯拉股票数据的 CSV 文件,并绘制了 2021 年价格的折线图。另外,我有 dates = [] 和一组日期,这我想在同一个折线图中绘制垂直线。

我的代码:

import pandas as pd
import matplotlib.pyplot as plt


"""
Stock Data
"""
path_to_stock_file = "/path/to/file/data/TSLA-USD.csv"
stock_df = pd.read_csv(path_to_stock_file)
in_year = stock_df[stock_df["Date"].str.contains("2021")]

dates = [] # this list consists of a collection of dates 

"""
Plot
"""
in_year["Close"].plot()
plt.figure(figsize=(100, 10))
in_year.index = in_year["Date"]
plt.plot(in_year.index, in_year["Close"])

for d in dates:
    plt.axvline(x=f"{d}", color="green")


plt.xlabel("date")
plt.ylabel("$ price")
plt.xticks(rotation=45)
plt.title("Tesla Stock Price 2021")
plt.show()

用于绘图的数据:

# stock date/price for line chart
{
    "2021-01-04": 729.77002,
    "2021-01-05": 735.109985,
    "2021-01-06": 755.97998,
    "2021-01-07": 816.039978,
    "2021-01-08": 880.02002,
    "2021-01-11": 811.190002,
    "2021-01-12": 849.440002,
    "2021-01-13": 854.409973,
    "2021-01-14": 845.0,
    "2021-01-15": 826.159973,
    "2021-01-19": 844.549988,
    "2021-01-20": 850.450012,
    "2021-01-21": 844.98999,
    "2021-01-22": 846.640015,
    "2021-01-25": 880.799988,
    "2021-01-26": 883.090027,
    "2021-01-27": 864.159973,
    "2021-01-28": 835.429993,
    "2021-01-29": 793.530029,
    "2021-02-01": 839.809998,
    "2021-02-02": 872.789978,
    "2021-02-03": 854.690002,
    "2021-02-04": 849.98999,
    "2021-02-05": 852.22998,
    "2021-02-08": 863.419983,
    "2021-02-09": 849.460022,
    "2021-02-10": 804.820007,
    "2021-02-11": 811.659973,
    "2021-02-12": 816.119995,
    "2021-02-16": 796.219971,
    "2021-02-17": 798.150024,
    "2021-02-18": 787.380005,
    "2021-02-19": 781.299988,
    "2021-02-22": 714.5,
    "2021-02-23": 698.840027,
    "2021-02-24": 742.02002,
    "2021-02-25": 682.219971,
    "2021-02-26": 675.5,
    "2021-03-01": 718.429993,
    "2021-03-02": 686.440002,
    "2021-03-03": 653.200012,
    "2021-03-04": 621.440002,
    "2021-03-05": 597.950012,
    "2021-03-08": 563.0,
    "2021-03-09": 673.580017,
    "2021-03-10": 668.059998,
    "2021-03-11": 699.599976,
    "2021-03-12": 693.72998,
    "2021-03-15": 707.940002,
    "2021-03-16": 676.880005,
    "2021-03-17": 701.809998,
    "2021-03-18": 653.159973,
    "2021-03-19": 654.869995,
    "2021-03-22": 670.0,
    "2021-03-23": 662.159973,
    "2021-03-24": 630.27002,
    "2021-03-25": 640.390015,
    "2021-03-26": 618.710022,
    "2021-03-29": 611.289978,
    "2021-03-30": 635.619995,
    "2021-03-31": 667.929993,
    "2021-04-01": 661.75,
    "2021-04-05": 691.049988,
    "2021-04-06": 691.619995,
    "2021-04-07": 670.969971,
    "2021-04-08": 683.799988,
    "2021-04-09": 677.02002,
    "2021-04-12": 701.97998,
    "2021-04-13": 762.320007,
    "2021-04-14": 732.22998,
    "2021-04-15": 738.849976,
    "2021-04-16": 739.780029,
    "2021-04-19": 714.630005,
    "2021-04-20": 718.98999,
    "2021-04-21": 744.119995,
    "2021-04-22": 719.690002,
    "2021-04-23": 729.400024,
    "2021-04-26": 738.200012,
    "2021-04-27": 704.73999,
    "2021-04-28": 694.400024,
    "2021-04-29": 677.0,
    "2021-04-30": 709.440002,
    "2021-05-03": 684.900024,
    "2021-05-04": 673.599976,
    "2021-05-05": 670.940002,
    "2021-05-06": 663.539978,
    "2021-05-07": 672.369995,
    "2021-05-10": 629.039978,
    "2021-05-11": 617.200012,
    "2021-05-12": 589.890015,
    "2021-05-13": 571.690002,
    "2021-05-14": 589.73999,
    "2021-05-17": 576.830017,
    "2021-05-18": 577.869995,
    "2021-05-19": 563.460022,
    "2021-05-20": 586.780029,
    "2021-05-21": 580.880005,
    "2021-05-24": 606.440002,
    "2021-05-25": 604.690002,
    "2021-05-26": 619.130005,
    "2021-05-27": 630.849976,
    "2021-05-28": 625.219971,
    "2021-06-01": 623.900024,
    "2021-06-02": 605.119995,
    "2021-06-03": 572.840027,
    "2021-06-04": 599.049988,
    "2021-06-07": 605.130005,
    "2021-06-08": 603.590027,
    "2021-06-09": 598.780029,
    "2021-06-10": 610.119995,
    "2021-06-11": 609.890015,
    "2021-06-14": 617.690002,
    "2021-06-15": 599.359985,
    "2021-06-16": 604.869995,
    "2021-06-17": 616.599976,
    "2021-06-18": 623.309998,
    "2021-06-21": 620.830017,
    "2021-06-22": 623.710022,
    "2021-06-23": 656.570007,
    "2021-06-24": 679.820007,
    "2021-06-25": 671.869995,
    "2021-06-28": 688.719971,
    "2021-06-29": 680.76001,
    "2021-06-30": 679.700012,
    "2021-07-01": 677.919983,
    "2021-07-02": 678.900024,
    "2021-07-06": 659.580017,
    "2021-07-07": 644.650024,
    "2021-07-08": 652.809998,
    "2021-07-09": 656.950012,
    "2021-07-12": 685.700012,
    "2021-07-13": 668.539978,
    "2021-07-14": 653.380005,
    "2021-07-15": 650.599976,
    "2021-07-16": 644.219971,
    "2021-07-19": 646.219971,
    "2021-07-20": 660.5,
    "2021-07-21": 655.289978,
    "2021-07-22": 649.26001,
    "2021-07-23": 643.380005,
    "2021-07-26": 657.619995,
    "2021-07-27": 644.780029,
    "2021-07-28": 646.97998,
    "2021-07-29": 677.349976,
    "2021-07-30": 687.200012,
    "2021-08-02": 709.669983,
    "2021-08-03": 709.73999,
    "2021-08-04": 710.919983,
    "2021-08-05": 714.630005,
    "2021-08-06": 699.099976,
    "2021-08-09": 713.76001,
    "2021-08-10": 709.98999,
    "2021-08-11": 707.820007,
    "2021-08-12": 722.25,
    "2021-08-13": 717.169983,
    "2021-08-16": 686.169983,
    "2021-08-17": 665.710022,
    "2021-08-18": 688.98999,
    "2021-08-19": 673.469971,
    "2021-08-20": 680.26001,
    "2021-08-23": 706.299988,
    "2021-08-24": 708.48999,
    "2021-08-25": 711.200012,
    "2021-08-26": 701.159973,
    "2021-08-27": 711.919983,
    "2021-08-30": 730.909973,
    "2021-08-31": 735.719971,
    "2021-09-01": 734.090027,
    "2021-09-02": 732.390015,
    "2021-09-03": 733.570007,
    "2021-09-07": 752.919983,
    "2021-09-08": 753.869995,
    "2021-09-09": 754.859985,
    "2021-09-10": 736.27002,
    "2021-09-13": 743.0,
    "2021-09-14": 744.48999,
    "2021-09-15": 755.830017,
    "2021-09-16": 756.98999,
    "2021-09-17": 759.48999,
    "2021-09-20": 730.169983,
    "2021-09-21": 739.380005,
    "2021-09-22": 751.940002,
    "2021-09-23": 753.640015,
    "2021-09-24": 774.390015,
    "2021-09-27": 791.359985,
    "2021-09-28": 777.559998,
    "2021-09-29": 781.309998,
    "2021-09-30": 775.47998,
    "2021-10-01": 775.219971,
    "2021-10-04": 781.530029,
    "2021-10-05": 780.590027,
    "2021-10-06": 782.75,
    "2021-10-07": 793.609985,
    "2021-10-08": 785.48999,
    "2021-10-11": 791.940002,
    "2021-10-12": 805.719971,
    "2021-10-13": 811.080017,
    "2021-10-14": 818.320007,
    "2021-10-15": 843.030029,
    "2021-10-18": 870.109985,
    "2021-10-19": 864.27002,
    "2021-10-20": 865.799988,
    "2021-10-21": 894.0,
    "2021-10-22": 909.679993,
    "2021-10-25": 1024.859985,
    "2021-10-26": 1018.429993,
    "2021-10-27": 1037.859985,
    "2021-10-28": 1077.040039,
    "2021-10-29": 1114.0,
    "2021-11-01": 1208.589966,
    "2021-11-02": 1172.0,
    "2021-11-03": 1213.859985,
    "2021-11-04": 1229.910034,
    "2021-11-05": 1222.089966,
    "2021-11-08": 1162.939941,
    "2021-11-09": 1023.5,
    "2021-11-10": 1067.949951,
    "2021-11-11": 1063.51001,
    "2021-11-12": 1033.420044,
    "2021-11-15": 1013.390015,
    "2021-11-16": 1054.72998,
    "2021-11-17": 1089.01001,
    "2021-11-18": 1096.380005,
    "2021-11-19": 1137.060059,
    "2021-11-22": 1156.869995,
    "2021-11-23": 1109.030029,
    "2021-11-24": 1116.0,
    "2021-11-26": 1081.920044,
    "2021-11-29": 1136.98999,
    "2021-11-30": 1144.76001,
    "2021-12-01": 1095.0,
    "2021-12-02": 1084.599976,
    "2021-12-03": 1014.969971,
    "2021-12-06": 1009.01001,
    "2021-12-07": 1051.75,
    "2021-12-08": 1068.959961,
    "2021-12-09": 1003.799988,
    "2021-12-10": 1017.030029,
    "2021-12-13": 966.409973,
    "2021-12-14": 958.51001,
    "2021-12-15": 975.98999,
    "2021-12-16": 926.919983,
    "2021-12-17": 932.570007,
    "2021-12-20": 899.940002,
    "2021-12-21": 938.530029,
    "2021-12-22": 1008.869995,
    "2021-12-23": 1067.0,
    "2021-12-27": 1093.939941,
    "2021-12-28": 1088.469971,
    "2021-12-29": 1086.189941,
    "2021-12-30": 1070.339966,
    "2021-12-31": 1056.780029,
}

# specific dates for vertical lines
[
    "2021-12-24",
    "2021-12-23",
    "2021-12-23",
    "2021-12-23",
    "2021-12-18",
    "2021-12-14",
    "2021-12-06",
    "2021-12-01",
    "2021-11-06",
    "2021-11-01",
    "2021-10-08",
    "2021-10-08",
    "2021-10-02",
    "2021-09-10",
    "2021-09-10",
    "2021-08-05",
    "2021-07-29",
    "2021-07-10",
    "2021-07-02",
    "2021-06-24",
    "2021-06-21",
    "2021-06-11",
    "2021-05-20",
    "2021-05-19",
    "2021-05-13",
    "2021-05-11",
    "2021-04-22",
    "2021-04-22",
    "2021-04-22",
    "2021-04-18",
    "2021-04-15",
    "2021-04-08",
    "2021-03-24",
    "2021-03-24",
    "2021-03-14",
    "2021-03-07",
    "2021-03-06",
    "2021-02-07",
    "2021-01-02",
]

结果图表:

如您所见,只有 dates = [] 中的日期在股票数据中也有关联的日期已被正确绘制。 dates = [] 在 x 轴(股票价格日期)上没有 关联日期的所有日期都绘制在图表的末尾。

由于股市有交易时间,因此数据总会有一些缺口,没有 date/price 可用。

有没有人知道我该如何解决这个问题?

创建一个带有 DatetimeIndex 的 DataFrame(不仅仅是字符串),但您可以安全地将与垂直线对应的日期保留为 yyyy-mm-dd 格式的字符串。您的绘图代码可以稍微清理一下,这可能是问题的一部分。

设置

根据您的样本数据,其中 plot_dict 是您的绘图值字典,dates 是您的日期字符串列表:

in_year = pd.DataFrame.from_dict(plot_dict, orient='index')
in_year.index = pd.to_datetime(in_year.index)

修改绘图代码

import pandas as pd
import matplotlib.pyplot as plt

in_year.plot(legend=None)

for d in dates:
    plt.axvline(x=f"{d}", color="green")

plt.xlabel("date")
plt.ylabel("$ price")
plt.xticks(rotation=45)
plt.title("Tesla Stock Price 2021")
plt.show()

结果