如何在 Matplotlib 中使用 Pandas 正确绘制这两个数据集?
How can I properly graph these two datasets using Pandas in Matplotlib?
我有两个数据集,我试图相互绘制。
第一个数据集是狗狗币的每日价格。我正在使用 yfinance 和 mplfinance 来绘制图表。
第二个数据集是狗狗币钱包 t运行sactions 的 CSV 文件,其中有一列名为“余额”,显示了狗狗币钱包在 t[=30= 时的余额]行动。余额随着加密货币的出现而波动 in/out。以下是供参考的 CSV。
https://www.mediafire.com/file/x53x9bowjrrcook/DSb5CvAXhXnzFoxmiMaWpgxjDF6CfMK7h2.csv/file
我正在尝试将余额作为折线图,以显示余额的波动。
下面是我的代码。我试图用这段代码完成的是绘制狗狗币价格图表,然后将 CSV 中的余额绘制成折线图,并将图表相互叠加。当显示在图表上时,我试图让两个数据集的日期相同,以便正确显示数据。
第一个问题是我一直无法弄清楚如何将这两个图表相互绘制。第一张图表来自 mplfinance,第二张图表来自 matplotlib。如果这两个模块不能相互叠加,那么我可以使用每日狗狗币价格的 csv 代替 mplfinance 和 yfinance。
我遇到的第二个问题 运行 是当余额减少时我的余额图不会波动,它只会增加。
import yfinance as yf
import matplotlib
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
import mplfinance as mpf
#This charts the Dogecoin Price
df = yf.Ticker("DOGE-USD").history(period='max')
df = df.loc["2021-01-01":]
mpf.plot(df, type="candle")
#This charts the balance from CSV
parse_dates = ['Time']
df = pd.read_csv('DSb5CvAXhXnzFoxmiMaWpgxjDF6CfMK7h2.csv', index_col=0, parse_dates=parse_dates)
plt.plot(df["Time"], df["Balance"])
plt.gca().invert_yaxis()
plt.show()
在排列两个数据集的时间戳之前,csv 文件存在许多问题,必须先清理。
这是您正在阅读的 csv 文件的样子:
df = pd.read_csv('DSb5CvAXhXnzFoxmiMaWpgxjDF6CfMK7h2.csv', index_col=0, parse_dates=parse_dates)
Time Amount Balance Balance, USD @ Price Profit
Block
4073636 2022-01-23 02:20:27 UTC 2022-01-23 02:20:27+00:00 +20,000 DOGE (2,707.16 USD) 2,740,510.04941789 DOGE 0,950 @ [=21=].135 4,009
4063557 2022-01-15 14:37:15 UTC 2022-01-15 14:37:15+00:00 -676,245.18946621 DOGE (128,175.63 USD) 2,720,510.04941789 DOGE 5,646 @ [=21=].19 1,413
4014695 2021-12-10 14:24:11 UTC 2021-12-10 14:24:11+00:00 +129,967 DOGE (21,907.16 USD) 3,396,755.2388841 DOGE 2,555 @ [=21=].169 0,146
4014652 2021-12-10 13:39:36 UTC 2021-12-10 13:39:36+00:00 +20,000 DOGE (3,466.9 USD) 3,266,788.2388841 DOGE 6,282 @ [=21=].173 5,780
4014275 2021-12-10 06:56:33 UTC 2021-12-10 06:56:33+00:00 +1,980,000 DOGE (331,523.17 USD) 3,246,788.2388841 DOGE 3,629 @ [=21=].167 6,594
有关此文件的几点注意事项:
- 时间戳同时存在于时间列和块列(您已设置为索引)中,但块列还在其时间戳旁边包含块号。
- 余额列包含单词“DOGE”,因此显然是一个字符串(不是浮点数)。
- 实际上,所有这样从csv文件中读出的列,都是字符串(Time列除外,由于
parse_dates
).
我建议,开始时,只阅读时间和平衡列,并将时间列设置为索引。同时可以对数据进行倒序,使时间顺序从早到晚:
dfb = pd.read_csv('DSb5CvAXhXnzFoxmiMaWpgxjDF6CfMK7h2.csv',usecols=['Time','Balance'],index_col=0, parse_dates=True)
dfb = dfb.iloc[::-1] # reverse the data
print(dfb.head(8))
Balance
Time
2021-04-24 10:20:22+00:00 47 DOGE
2021-04-24 10:34:39+00:00 57 DOGE
2021-04-24 10:40:49+00:00 67 DOGE
2021-04-24 10:42:22+00:00 58 DOGE
2021-04-24 10:50:46+00:00 49 DOGE
2021-04-26 09:48:52+00:00 19,049 DOGE
2021-04-26 13:39:54+00:00 49 DOGE
2021-04-26 16:22:06+00:00 20,099 DOGE
现在您可以通过将列字符串拆分为实际余额和单词“DOGE”并将实际余额转换为浮点数来清理余额列:
dfb["Balance"] = dfb["Balance"].str.split(expand=True).iloc[:,0] # [:,0] to take only balance and throw away "DOGE"
dfb["Balance"] = dfb["Balance"].str.replace(',','').astype(float) # remove commas from balance and convert to float.
print(dfb.head(16))
print(dfb.tail())
Balance
Time
2021-04-24 10:20:22+00:00 4.700000e+01
2021-04-24 10:34:39+00:00 5.700000e+01
2021-04-24 10:40:49+00:00 6.700000e+01
2021-04-24 10:42:22+00:00 5.800000e+01
2021-04-24 10:50:46+00:00 4.900000e+01
2021-04-26 09:48:52+00:00 1.904900e+04
2021-04-26 13:39:54+00:00 4.900000e+01
2021-04-26 16:22:06+00:00 2.009900e+04
2021-04-27 16:18:41+00:00 8.901000e+02
2021-04-29 15:37:30+00:00 2.500800e+04
2021-04-29 18:08:48+00:00 4.500800e+04
2021-04-29 18:21:54+00:00 7.999429e+04
2021-04-29 18:55:09+00:00 1.049685e+05
2021-04-30 02:48:24+00:00 8.049615e+05
2021-04-30 03:28:13+00:00 2.004911e+06
2021-04-30 04:36:35+00:00 1.985752e+06
Balance
Time
2021-12-10 06:56:33+00:00 3.246788e+06
2021-12-10 13:39:36+00:00 3.266788e+06
2021-12-10 14:24:11+00:00 3.396755e+06
2022-01-15 14:37:15+00:00 2.720510e+06
2022-01-23 02:20:27+00:00 2.740510e+06
现在看一下来自yfinance的数据,并将其与csv文件数据进行比较:
df = yf.Ticker("DOGE-USD").history(period='max')
df = df.loc["2021-01-01":]
print(df.head(8))
print(df.tail())
Open High Low Close Volume Dividends Stock Splits
Date
2021-01-01 0.004681 0.005685 0.004615 0.005685 228961515 0 0
2021-01-02 0.005686 0.013698 0.005584 0.010615 3421562680 0 0
2021-01-03 0.010602 0.013867 0.009409 0.009771 2707003608 0 0
2021-01-04 0.009785 0.011421 0.007878 0.009767 1372398979 0 0
2021-01-05 0.009767 0.010219 0.008972 0.009920 687256067 0 0
2021-01-06 0.009923 0.010854 0.009685 0.010465 749915516 0 0
2021-01-07 0.010454 0.010532 0.009162 0.009742 520644706 0 0
2021-01-08 0.009743 0.010285 0.008986 0.009846 394462164 0 0
Open High Low Close Volume Dividends Stock Splits
Date
2022-01-22 0.142651 0.145027 0.122816 0.132892 1693524581 0 0
2022-01-23 0.132960 0.143072 0.132819 0.141863 1006234946 0 0
2022-01-24 0.141881 0.141951 0.127220 0.137798 1446873574 0 0
2022-01-25 0.137784 0.147236 0.133235 0.143049 1347567750 0 0
2022-01-26 0.142737 0.146615 0.142239 0.146615 1371126400 0 0
有两点需要注意:
- yfinance的数据每天只有一行
- csv数据有
- 每天多行
- 有些日子的行数比其他日子多
- 有些日子完全不见了
为了能够加入两个数据集,我建议首先重新采样 余额数据,这样您每天只有一行。我还建议这样做,每天的余额 是该日期的最终余额 。这可以使用 pandas 的 ohlc()
(开盘价、最高价、最低价、收盘价)聚合器来完成,然后只需将每一天的“收盘价”作为该日期的最终余额:
newdfb = dfb['Balance'].resample('D').ohlc().dropna() # dropna gets rid of rows that have no data
newdfb.drop(['open','high','low'],axis=1,inplace=True) # keep only "close"
newdfb.columns = ['Balance'] # rename "close" to "Balance"
print(newdfb.head())
Balance
Time
2021-04-24 00:00:00+00:00 4.900000e+01
2021-04-26 00:00:00+00:00 2.009900e+04
2021-04-27 00:00:00+00:00 8.901000e+02
2021-04-29 00:00:00+00:00 1.049685e+05
2021-04-30 00:00:00+00:00 2.665753e+06
现在,在我们连接两个数据帧之前,请注意 yfinance 数据帧的索引中只有 日期 ,而余额数据具有完整的时间戳。我们可以将余额数据转换为索引中只有日期,如下所示:
dates = [d.date() for d in newdfb.index]
newdfb.index = pd.DatetimeIndex(dates)
newdfb.index.name = 'Time'
print(newdfb.head())
Balance
Time
2021-04-24 4.900000e+01
2021-04-26 2.009900e+04
2021-04-27 8.901000e+02
2021-04-29 1.049685e+05
2021-04-30 2.665753e+06
现在我们可以连接两个数据框了。 DataFrame.join() 将根据索引加入数据帧,在我们的例子中是日期,因此数据将按日期对齐。此外,我们将进行 outer 连接,并且 .dropna()
以便 只有存在于两个数据框中的日期才会包含在最终数据框中。这是能够将数据一起绘制在同一图上的最干净的方法:
dfc = df.join(newdfb, how='outer').dropna()
dfc.index.name = 'Date'
print(dfc.head())
print(dfc.tail())
Open High Low Close Volume Dividends Stock Splits Balance
Date
2021-04-24 0.249544 0.289390 0.229891 0.270212 11057578568 0 0 4.900000e+01
2021-04-26 0.251240 0.280452 0.248026 0.270674 5118886527 0 0 2.009900e+04
2021-04-27 0.271427 0.279629 0.264928 0.272188 3590611310 0 0 8.901000e+02
2021-04-29 0.323232 0.323881 0.296904 0.305169 5027354503 0 0 1.049685e+05
2021-04-30 0.304702 0.339757 0.302981 0.337561 5290390982 0 0 2.665753e+06
Open High Low Close Volume Dividends Stock Splits Balance
Date
2021-09-19 0.241281 0.241285 0.231337 0.233142 892763953 0 0 1.246787e+06
2021-11-27 0.201429 0.209613 0.200871 0.205347 917785649 0 0 1.246788e+06
2021-12-10 0.169466 0.174610 0.164065 0.164422 845450410 0 0 3.396755e+06
2022-01-15 0.183644 0.193600 0.182676 0.185103 1878282290 0 0 2.720510e+06
2022-01-23 0.132960 0.143072 0.132819 0.141863 1006234946 0 0 2.740510e+06
现在终于可以绘制 'Balance' 和 ohlc 烛台了:
ap = mpf.make_addplot(dfc['Balance'])
mpf.plot(dfc,type='candle',addplot=ap)
这是结果图:
我有两个数据集,我试图相互绘制。
第一个数据集是狗狗币的每日价格。我正在使用 yfinance 和 mplfinance 来绘制图表。
第二个数据集是狗狗币钱包 t运行sactions 的 CSV 文件,其中有一列名为“余额”,显示了狗狗币钱包在 t[=30= 时的余额]行动。余额随着加密货币的出现而波动 in/out。以下是供参考的 CSV。
https://www.mediafire.com/file/x53x9bowjrrcook/DSb5CvAXhXnzFoxmiMaWpgxjDF6CfMK7h2.csv/file
我正在尝试将余额作为折线图,以显示余额的波动。
下面是我的代码。我试图用这段代码完成的是绘制狗狗币价格图表,然后将 CSV 中的余额绘制成折线图,并将图表相互叠加。当显示在图表上时,我试图让两个数据集的日期相同,以便正确显示数据。
第一个问题是我一直无法弄清楚如何将这两个图表相互绘制。第一张图表来自 mplfinance,第二张图表来自 matplotlib。如果这两个模块不能相互叠加,那么我可以使用每日狗狗币价格的 csv 代替 mplfinance 和 yfinance。
我遇到的第二个问题 运行 是当余额减少时我的余额图不会波动,它只会增加。
import yfinance as yf
import matplotlib
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
import mplfinance as mpf
#This charts the Dogecoin Price
df = yf.Ticker("DOGE-USD").history(period='max')
df = df.loc["2021-01-01":]
mpf.plot(df, type="candle")
#This charts the balance from CSV
parse_dates = ['Time']
df = pd.read_csv('DSb5CvAXhXnzFoxmiMaWpgxjDF6CfMK7h2.csv', index_col=0, parse_dates=parse_dates)
plt.plot(df["Time"], df["Balance"])
plt.gca().invert_yaxis()
plt.show()
在排列两个数据集的时间戳之前,csv 文件存在许多问题,必须先清理。
这是您正在阅读的 csv 文件的样子:
df = pd.read_csv('DSb5CvAXhXnzFoxmiMaWpgxjDF6CfMK7h2.csv', index_col=0, parse_dates=parse_dates)
Time Amount Balance Balance, USD @ Price Profit Block 4073636 2022-01-23 02:20:27 UTC 2022-01-23 02:20:27+00:00 +20,000 DOGE (2,707.16 USD) 2,740,510.04941789 DOGE 0,950 @ [=21=].135 4,009 4063557 2022-01-15 14:37:15 UTC 2022-01-15 14:37:15+00:00 -676,245.18946621 DOGE (128,175.63 USD) 2,720,510.04941789 DOGE 5,646 @ [=21=].19 1,413 4014695 2021-12-10 14:24:11 UTC 2021-12-10 14:24:11+00:00 +129,967 DOGE (21,907.16 USD) 3,396,755.2388841 DOGE 2,555 @ [=21=].169 0,146 4014652 2021-12-10 13:39:36 UTC 2021-12-10 13:39:36+00:00 +20,000 DOGE (3,466.9 USD) 3,266,788.2388841 DOGE 6,282 @ [=21=].173 5,780 4014275 2021-12-10 06:56:33 UTC 2021-12-10 06:56:33+00:00 +1,980,000 DOGE (331,523.17 USD) 3,246,788.2388841 DOGE 3,629 @ [=21=].167 6,594
有关此文件的几点注意事项:
- 时间戳同时存在于时间列和块列(您已设置为索引)中,但块列还在其时间戳旁边包含块号。
- 余额列包含单词“DOGE”,因此显然是一个字符串(不是浮点数)。
- 实际上,所有这样从csv文件中读出的列,都是字符串(Time列除外,由于
parse_dates
).
我建议,开始时,只阅读时间和平衡列,并将时间列设置为索引。同时可以对数据进行倒序,使时间顺序从早到晚:
dfb = pd.read_csv('DSb5CvAXhXnzFoxmiMaWpgxjDF6CfMK7h2.csv',usecols=['Time','Balance'],index_col=0, parse_dates=True)
dfb = dfb.iloc[::-1] # reverse the data
print(dfb.head(8))
Balance Time 2021-04-24 10:20:22+00:00 47 DOGE 2021-04-24 10:34:39+00:00 57 DOGE 2021-04-24 10:40:49+00:00 67 DOGE 2021-04-24 10:42:22+00:00 58 DOGE 2021-04-24 10:50:46+00:00 49 DOGE 2021-04-26 09:48:52+00:00 19,049 DOGE 2021-04-26 13:39:54+00:00 49 DOGE 2021-04-26 16:22:06+00:00 20,099 DOGE
现在您可以通过将列字符串拆分为实际余额和单词“DOGE”并将实际余额转换为浮点数来清理余额列:
dfb["Balance"] = dfb["Balance"].str.split(expand=True).iloc[:,0] # [:,0] to take only balance and throw away "DOGE"
dfb["Balance"] = dfb["Balance"].str.replace(',','').astype(float) # remove commas from balance and convert to float.
print(dfb.head(16))
print(dfb.tail())
Balance Time 2021-04-24 10:20:22+00:00 4.700000e+01 2021-04-24 10:34:39+00:00 5.700000e+01 2021-04-24 10:40:49+00:00 6.700000e+01 2021-04-24 10:42:22+00:00 5.800000e+01 2021-04-24 10:50:46+00:00 4.900000e+01 2021-04-26 09:48:52+00:00 1.904900e+04 2021-04-26 13:39:54+00:00 4.900000e+01 2021-04-26 16:22:06+00:00 2.009900e+04 2021-04-27 16:18:41+00:00 8.901000e+02 2021-04-29 15:37:30+00:00 2.500800e+04 2021-04-29 18:08:48+00:00 4.500800e+04 2021-04-29 18:21:54+00:00 7.999429e+04 2021-04-29 18:55:09+00:00 1.049685e+05 2021-04-30 02:48:24+00:00 8.049615e+05 2021-04-30 03:28:13+00:00 2.004911e+06 2021-04-30 04:36:35+00:00 1.985752e+06
Balance Time 2021-12-10 06:56:33+00:00 3.246788e+06 2021-12-10 13:39:36+00:00 3.266788e+06 2021-12-10 14:24:11+00:00 3.396755e+06 2022-01-15 14:37:15+00:00 2.720510e+06 2022-01-23 02:20:27+00:00 2.740510e+06
现在看一下来自yfinance的数据,并将其与csv文件数据进行比较:
df = yf.Ticker("DOGE-USD").history(period='max')
df = df.loc["2021-01-01":]
print(df.head(8))
print(df.tail())
Open High Low Close Volume Dividends Stock Splits Date 2021-01-01 0.004681 0.005685 0.004615 0.005685 228961515 0 0 2021-01-02 0.005686 0.013698 0.005584 0.010615 3421562680 0 0 2021-01-03 0.010602 0.013867 0.009409 0.009771 2707003608 0 0 2021-01-04 0.009785 0.011421 0.007878 0.009767 1372398979 0 0 2021-01-05 0.009767 0.010219 0.008972 0.009920 687256067 0 0 2021-01-06 0.009923 0.010854 0.009685 0.010465 749915516 0 0 2021-01-07 0.010454 0.010532 0.009162 0.009742 520644706 0 0 2021-01-08 0.009743 0.010285 0.008986 0.009846 394462164 0 0
Open High Low Close Volume Dividends Stock Splits Date 2022-01-22 0.142651 0.145027 0.122816 0.132892 1693524581 0 0 2022-01-23 0.132960 0.143072 0.132819 0.141863 1006234946 0 0 2022-01-24 0.141881 0.141951 0.127220 0.137798 1446873574 0 0 2022-01-25 0.137784 0.147236 0.133235 0.143049 1347567750 0 0 2022-01-26 0.142737 0.146615 0.142239 0.146615 1371126400 0 0
有两点需要注意:
- yfinance的数据每天只有一行
- csv数据有
- 每天多行
- 有些日子的行数比其他日子多
- 有些日子完全不见了
为了能够加入两个数据集,我建议首先重新采样 余额数据,这样您每天只有一行。我还建议这样做,每天的余额 是该日期的最终余额 。这可以使用 pandas 的 ohlc()
(开盘价、最高价、最低价、收盘价)聚合器来完成,然后只需将每一天的“收盘价”作为该日期的最终余额:
newdfb = dfb['Balance'].resample('D').ohlc().dropna() # dropna gets rid of rows that have no data
newdfb.drop(['open','high','low'],axis=1,inplace=True) # keep only "close"
newdfb.columns = ['Balance'] # rename "close" to "Balance"
print(newdfb.head())
Balance Time 2021-04-24 00:00:00+00:00 4.900000e+01 2021-04-26 00:00:00+00:00 2.009900e+04 2021-04-27 00:00:00+00:00 8.901000e+02 2021-04-29 00:00:00+00:00 1.049685e+05 2021-04-30 00:00:00+00:00 2.665753e+06
现在,在我们连接两个数据帧之前,请注意 yfinance 数据帧的索引中只有 日期 ,而余额数据具有完整的时间戳。我们可以将余额数据转换为索引中只有日期,如下所示:
dates = [d.date() for d in newdfb.index]
newdfb.index = pd.DatetimeIndex(dates)
newdfb.index.name = 'Time'
print(newdfb.head())
Balance Time 2021-04-24 4.900000e+01 2021-04-26 2.009900e+04 2021-04-27 8.901000e+02 2021-04-29 1.049685e+05 2021-04-30 2.665753e+06
现在我们可以连接两个数据框了。 DataFrame.join() 将根据索引加入数据帧,在我们的例子中是日期,因此数据将按日期对齐。此外,我们将进行 outer 连接,并且 .dropna()
以便 只有存在于两个数据框中的日期才会包含在最终数据框中。这是能够将数据一起绘制在同一图上的最干净的方法:
dfc = df.join(newdfb, how='outer').dropna()
dfc.index.name = 'Date'
print(dfc.head())
print(dfc.tail())
Open High Low Close Volume Dividends Stock Splits Balance Date 2021-04-24 0.249544 0.289390 0.229891 0.270212 11057578568 0 0 4.900000e+01 2021-04-26 0.251240 0.280452 0.248026 0.270674 5118886527 0 0 2.009900e+04 2021-04-27 0.271427 0.279629 0.264928 0.272188 3590611310 0 0 8.901000e+02 2021-04-29 0.323232 0.323881 0.296904 0.305169 5027354503 0 0 1.049685e+05 2021-04-30 0.304702 0.339757 0.302981 0.337561 5290390982 0 0 2.665753e+06
Open High Low Close Volume Dividends Stock Splits Balance Date 2021-09-19 0.241281 0.241285 0.231337 0.233142 892763953 0 0 1.246787e+06 2021-11-27 0.201429 0.209613 0.200871 0.205347 917785649 0 0 1.246788e+06 2021-12-10 0.169466 0.174610 0.164065 0.164422 845450410 0 0 3.396755e+06 2022-01-15 0.183644 0.193600 0.182676 0.185103 1878282290 0 0 2.720510e+06 2022-01-23 0.132960 0.143072 0.132819 0.141863 1006234946 0 0 2.740510e+06
现在终于可以绘制 'Balance' 和 ohlc 烛台了:
ap = mpf.make_addplot(dfc['Balance'])
mpf.plot(dfc,type='candle',addplot=ap)
这是结果图: