matplotlib Pandas条形图与折线图相结合显示了从1970年开始的时间轴

pxq42qpu  于 2023-03-13  发布在  其他
关注(0)|答案(2)|浏览(208)

我正在画一张股票市场的图表
时间序列对收盘价和时间序列对成交量。
X轴显示的是1970年的时间
下面是图表和代码

代码为:

import pandas as pd

import matplotlib.pyplot as plt
import matplotlib.dates as mdates

pd_data = pd.DataFrame(data, columns=['id', 'symbol', 'volume', 'high', 'low', 'open', 'datetime','close','datetime_utc','created_at'])

pd_data['DOB'] = pd.to_datetime(pd_data['datetime_utc']).dt.strftime('%Y-%m-%d') 

pd_data.set_index('DOB')

print(pd_data)

print(pd_data.dtypes)

ax=pd_data.plot(x='DOB',y='close',kind = 'line')
ax.set_ylabel("price")

#ax.pd_data['volume'].plot(secondary_y=True,  kind='bar')
ax1=pd_data.plot(y='volume',secondary_y=True, ax=ax,kind='bar')
ax1.set_ylabel('Volumne')

# Choose your xtick format string
date_fmt = '%d-%m-%y'

date_formatter = mdates.DateFormatter(date_fmt)
ax1.xaxis.set_major_formatter(date_formatter)

# set monthly locator
ax1.xaxis.set_major_locator(mdates.MonthLocator(interval=1))

# set font and rotation for date tick labels
plt.gcf().autofmt_xdate()

plt.show()

还在不使用ax=ax的情况下单独尝试了两个图表

ax=pd_data.plot(x='DOB',y='close',kind = 'line')
ax.set_ylabel("price")

ax1=pd_data.plot(y='volume',secondary_y=True,kind='bar')
ax1.set_ylabel('Volumne')

价格图显示年份,而成交量图显示1970年
如果我把它们换了

ax1=pd_data.plot(y='volume',secondary_y=True,kind='bar')
ax1.set_ylabel('Volumne')

ax=pd_data.plot(x='DOB',y='close',kind = 'line')
ax.set_ylabel("price")

现在,成交量图正确显示年份,而价格图显示的年份为1970年
我试着删除secondary_y,并将bar更改为line,但没有成功
不知何故,Pandas第一张图表之后的数据正在改变年份。

a0zr77ik

a0zr77ik1#

  • 我不建议绘制一个有这么多条的条形图。
  • 此答案解释了为什么xtick标签存在问题,以及如何解决此问题。
  • 使用pandas.DataFrame.plot进行打印不会出现问题
    *python 3.8.11pandas 1.3.2matplotlib 3.4.2中测试
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import yfinance as yf  # conda install -c conda-forge yfinance or pip install yfinance --upgrade --no-cache-dir

# download data
df = yf.download('amzn', start='2015-02-21', end='2021-04-27')

# plot
ax = df.plot(y='Close', color='magenta', ls='-.', figsize=(10, 6), ylabel='Price ($)')

ax1 = df.plot(y='Volume', secondary_y=True, ax=ax, alpha=0.5, rot=0, lw=0.5)
ax1.set(ylabel='Volume')

# format
date_fmt = '%d-%m-%y'
years = mdates.YearLocator()   # every year
yearsFmt = mdates.DateFormatter(date_fmt)

ax.xaxis.set_major_locator(years)
ax.xaxis.set_major_formatter(yearsFmt)

plt.setp(ax.get_xticklabels(), ha="center")
plt.show()

  • 为什么OP x-tick标签是从1970年开始的?
  • 条形图位置的索引为0(带有Pandas),0对应于1970年
  • 参见Pandas bar plot changes date format
  • 大多数具有条形图的解决方案只是将标注重新格式化为适当的日期时间,但这只是表面现象,不会对齐线图和条形图之间的位置
    *answer的解决方案2展示了如何更改刻度定位器,但在可以使用plt.bar时,确实不值得额外编写代码。

x一个一个一个一个x一个一个二个x

  • 对于plt.bar,条形图位置基于日期时间进行索引
ax = df.plot(y='Close', color='magenta', ls='-.', figsize=(10, 6), ylabel='Price ($)', rot=0)
plt.setp(ax.get_xticklabels(), ha="center")
print(ax.get_xticks())

ax1 = ax.twinx()
ax1.bar(df.index, df.Volume)
print(ax1.get_xticks())

date_fmt = '%d-%m-%y'
years = mdates.YearLocator()   # every year
yearsFmt = mdates.DateFormatter(date_fmt)

ax.xaxis.set_major_locator(years)
ax.xaxis.set_major_formatter(yearsFmt)

[out]:
[16071. 16436. 16801. 17167. 17532. 17897. 18262. 18628.]
[16071. 16436. 16801. 17167. 17532. 17897. 18262. 18628.]

  • sns.barplot(x=df.index, y=df.Volume, ax=ax1)xtick位置与[ 0 1 2 ... 1553 1554 1555]相同,因此条形图和折线图未对齐。
wwtsj6pe

wwtsj6pe2#

我找不到1970年的原因,而是使用matplotlib.pyplot绘图,而不是间接使用panda,并且传递datatime数组,而不是panda
所以下面的代码是有效的

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd
import datetime as dt
import numpy as np

pd_data = pd.read_csv("/home/stockdata.csv",sep='\t')

pd_data['DOB'] = pd.to_datetime(pd_data['datetime2']).dt.strftime('%Y-%m-%d')

dates=[dt.datetime.strptime(d,'%Y-%m-%d').date() for d in pd_data['DOB']]

plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m/%d/%Y'))
plt.gca().xaxis.set_major_locator(mdates.MonthLocator(interval=2))
plt.bar(dates,pd_data['close'],align='center')
plt.gca().xaxis.set_minor_locator(plt.MultipleLocator(1))
plt.gcf().autofmt_xdate()
plt.show()

我创建了一个日期时间格式的日期数组。如果我用它制作图表,那么日期就不会显示为1970年

open    high    low close   volume  datetime    datetime2
35.12   35.68   34.79   35.58   1432995 1244385200000   2012-6-15 10:30:00
35.69   36.02   35.37   35.78   1754319 1244371600000   2012-6-16 10:30:00
35.69   36.23   35.59   36.23   3685845 1245330800000   2012-6-19 10:30:00
36.11   36.52   36.03   36.32   2635777 1245317200000   2012-6-20 10:30:00
36.54   36.6    35.8    35.9    2886412 1245303600000   2012-6-21 10:30:00
36.03   36.95   36.0    36.09   3696278 1245390000000   2012-6-22 10:30:00
36.5    37.27   36.18   37.11   2732645 1245376400000   2012-6-23 10:30:00
36.98   37.11   36.686  36.83   1948411 1245335600000   2012-6-26 10:30:00
36.67   37.06   36.465  37.05   2557172 1245322000000   2012-6-27 10:30:00
37.06   37.61   36.77   37.52   1780126 1246308400000   2012-6-28 10:30:00
37.47   37.77   37.28   37.7    1352267 1246394800000   2012-6-29 10:30:00
37.72   38.1    37.68   37.76   2194619 1246381200000   2012-6-30 10:30:00

我得到的情节是

相关问题