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

我正在尝试绘制股票市场图表

时间序列与收盘价以及时间序列与交易量。

x 轴以某种方式显示 1970 年的时间

下面是图和代码

https://i.stack.imgur.com/THvGM.png

代码是:


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 并将条更改为行。但没有运气


不知何故,第一张图之后的 pandas 数据正在改变年份。


千巷猫影
浏览 133回答 3
3回答

慕斯王

我不建议绘制包含如此多条形图的条形图。此答案解释了xtick 标签存在问题的原因以及如何解决该问题。绘图与pandas.DataFrame.plot工作没有问题.set_major_locator测试于python 3.8.11, pandas 1.3.2,matplotlib 3.4.2import pandas as pdimport matplotlib.pyplot as pltimport matplotlib.dates as mdatesimport yfinance as yf  # conda install -c conda-forge yfinance or pip install yfinance --upgrade --no-cache-dir# download datadf = yf.download('amzn', start='2015-02-21', end='2021-04-27')# plotax = 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')# formatdate_fmt = '%d-%m-%y'years = mdates.YearLocator()   # every yearyearsFmt = 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()https://i.stack.imgur.com/8MHUi.png 为什么 OP x-tick 标签从 1970 年开始?条形图位置的索引为 0(使用 pandas),0 对应于 1970请参阅Pandas 条形图更改日期格式大多数带有条形图的解决方案只是将标签重新格式化为适当的日期时间,但是这是装饰性的,并且不会对齐线图和条形图之间的位置这个答案的解决方案 2显示了如何更改刻度定位器,但在plt.bar可以使用时确实不值得额外的代码。print(pd.to_datetime(ax1.get_xticks()))DatetimeIndex([          '1970-01-01 00:00:00',               '1970-01-01 00:00:00.000000001',               '1970-01-01 00:00:00.000000002',               '1970-01-01 00:00:00.000000003',               ...               '1970-01-01 00:00:00.000001552',               '1970-01-01 00:00:00.000001553',               '1970-01-01 00:00:00.000001554',               '1970-01-01 00:00:00.000001555'],              dtype='datetime64[ns]', length=1556, freq=None)ax = df.plot(y='Close', color='magenta', ls='-.', figsize=(10, 6), ylabel='Price ($)')print(ax.get_xticks())ax1 = df.plot(y='Volume', secondary_y=True, ax=ax, kind='bar')print(ax1.get_xticks())ax1.set_xlim(0, 18628.)date_fmt = '%d-%m-%y'years = mdates.YearLocator()   # every yearyearsFmt = 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.]  ← ax tick locations[   0    1    2 ... 1553 1554 1555]  ← ax1 tick locationshttps://i.stack.imgur.com/ytQfd.png 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 yearyearsFmt = 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.]https://i.stack.imgur.com/4MxzW.png sns.barplot(x=df.index, y=df.Volume, ax=ax1)xtick位置为,[   0    1    2 ... 1553 1554 1555]因此条形图和线图未对齐。

潇潇雨雨

我找不到 1970 的原因,而是使用 matplotlib.pyplot 进行绘图而不是间接使用 pandas 并传递 datatime 数组而不是 pandas所以下面的代码有效import matplotlib.pyplot as pltimport matplotlib.dates as mdatesimport pandas as pdimport datetime as dtimport numpy as nppd_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    datetime235.12   35.68   34.79   35.58   1432995 1244385200000   2012-6-15 10:30:0035.69   36.02   35.37   35.78   1754319 1244371600000   2012-6-16 10:30:0035.69   36.23   35.59   36.23   3685845 1245330800000   2012-6-19 10:30:0036.11   36.52   36.03   36.32   2635777 1245317200000   2012-6-20 10:30:0036.54   36.6    35.8    35.9    2886412 1245303600000   2012-6-21 10:30:0036.03   36.95   36.0    36.09   3696278 1245390000000   2012-6-22 10:30:0036.5    37.27   36.18   37.11   2732645 1245376400000   2012-6-23 10:30:0036.98   37.11   36.686  36.83   1948411 1245335600000   2012-6-26 10:30:0036.67   37.06   36.465  37.05   2557172 1245322000000   2012-6-27 10:30:0037.06   37.61   36.77   37.52   1780126 1246308400000   2012-6-28 10:30:0037.47   37.77   37.28   37.7    1352267 1246394800000   2012-6-29 10:30:0037.72   38.1    37.68   37.76   2194619 1246381200000   2012-6-30 10:30:00我得到的情节是https://i.stack.imgur.com/lrtEN.png

幕布斯6054654

首先,您必须指定日期格式,然后在底部指定 Y 轴以仅显示“%Y”年# Convert 'Filing date' to a datetime format (assuming it's not already)df_transposed['Filing date'] = pd.to_datetime(df_transposed['Filing date'], format='%Y-%m-%d')  # Specify the format...# Create a figure with two y-axesfig, ax1 = plt.subplots(figsize=(16, 6))# Create a bar chart for Total Revenue against Filing Date on the first y-axisax1.bar(df_filtered['Filing date'], df_filtered['Total Revenue'], color='b', align='center', alpha=0.5, width=50)  # Adjust bar width as neededax1.set_xlabel('Year')ax1.set_ylabel('Total Revenue in Billions')ax1.set_title('Total Revenue Over Years Bar Chart and Line Chart')ax1.tick_params(axis='x', rotation=45)# Adjust the transparency (alpha) of the horizontal grid lines to make them more faintax1.grid(axis='x', alpha=0.5)# Create a line chart for Total Revenue against Filing Date on the second y-axisax2 = ax1.twinx()ax2.plot(df_filtered['Filing date'], df_filtered['Total Revenue'], '-', color='r')ax2.set_ylabel('Total Revenue in Billions (Line Chart)')# Adjust the y-axis limits to match between both axesmin_y = min(ax1.get_ylim()[0], ax2.get_ylim()[0])max_y = max(ax1.get_ylim()[1], ax2.get_ylim()[1])ax1.set_ylim(min_y, max_y)ax2.set_ylim(min_y, max_y)# Set the x-axis to display only yearsplt.gca().xaxis.set_major_formatter(plt.matplotlib.dates.DateFormatter('%Y'))# Show the combined chartplt.tight_layout()plt.show()
打开App,查看更多内容
随时随地看视频慕课网APP