3 回答

TA貢獻1864條經驗 獲得超2個贊
我不建議繪制包含如此多條形圖的條形圖。
此答案解釋了xtick 標簽存在問題的原因以及如何解決該問題。
繪圖與pandas.DataFrame.plot工作沒有問題.set_major_locator
測試于python 3.8.11, pandas 1.3.2,matplotlib 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()
https://i.stack.imgur.com/8MHUi.png
為什么 OP x-tick 標簽從 1970 年開始?
條形圖位置的索引為 0(使用 pandas),0 對應于 1970
大多數帶有條形圖的解決方案只是將標簽重新格式化為適當的日期時間,但是這是裝飾性的,并且不會對齊線圖和條形圖之間的位置
這個答案的解決方案 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 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.] ← ax tick locations
[ 0 1 2 ... 1553 1554 1555] ← ax1 tick locations
https://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 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.]
https://i.stack.imgur.com/4MxzW.png
sns.barplot(x=df.index, y=df.Volume, ax=ax1)
xtick
位置為,[ 0 1 2 ... 1553 1554 1555]
因此條形圖和線圖未對齊。

TA貢獻1833條經驗 獲得超4個贊
我找不到 1970 的原因,而是使用 matplotlib.pyplot 進行繪圖而不是間接使用 pandas 并傳遞 datatime 數組而不是 pandas
所以下面的代碼有效
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
我得到的情節是
https://i.stack.imgur.com/lrtEN.png

TA貢獻1876條經驗 獲得超7個贊
首先,您必須指定日期格式,然后在底部指定 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-axes
fig, ax1 = plt.subplots(figsize=(16, 6))
# Create a bar chart for Total Revenue against Filing Date on the first y-axis
ax1.bar(df_filtered['Filing date'], df_filtered['Total Revenue'], color='b', align='center', alpha=0.5, width=50) # Adjust bar width as needed
ax1.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 faint
ax1.grid(axis='x', alpha=0.5)
# Create a line chart for Total Revenue against Filing Date on the second y-axis
ax2 = 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 axes
min_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 years
plt.gca().xaxis.set_major_formatter(plt.matplotlib.dates.DateFormatter('%Y'))
# Show the combined chart
plt.tight_layout()
plt.show()
- 3 回答
- 0 關注
- 223 瀏覽
添加回答
舉報