Python 在同一轴上绘制多年数据时定义 xlim
Python defining xlim when when plotting multiple year data on same axis
我想在同一个轴上绘制几年的数据。 很有用,但我似乎无法定义 xlim
。 MWE 是
import numpy as np
import pandas as pd
from datetime import datetime, date, timedelta
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.ticker as tkr
data15 = pd.DataFrame([1,2,3,4,5,6,7,8,9,10,11,12], index=pd.date_range(start='2015-01',end='2016-01',freq='M'), columns=['2015'])
data16 = pd.DataFrame([5,4,3,2,1], index=pd.date_range(start='2016-01',end='2016-06',freq='M'), columns=['2016'])
data15['month'] = data15.index.to_series().dt.strftime('%b')
data16['month'] = data16.index.to_series().dt.strftime('%b')
ax = data16.plot(x='month', y='2016')
ax = data15.plot(x='month', y='2015', ax=ax)
ax.xaxis.set_major_locator(mdates.DayLocator(interval=1))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b'))
plt.setp(ax.get_xticklabels()[::2], visible=False)
ax.set_xlim(data16.month[0], data16.month[-1])
plt.show()
不管我怎么改都只想显示前两个数据点xlim
。我该如何解决这个问题?
没有set_xlim
的图是
所以 ax.set_xlim(data16.month[0], data16.month[-1])
行应该只显示 Jan
和 May
之间的点。
目前还不清楚数据帧的条件是什么,但将 pandas matplotlib 便利包装器与 higher-end matplotlib 函数混合使用通常会产生问题。假设每个数据帧恰好存在一个每月数据点,您可以提取月份编号并使用月份名称重新标记 x-axis:
import pandas as pd
import matplotlib.pyplot as plt
import calendar
data15 = pd.DataFrame([1,2,3,4,5,6,7,8,9,10,11,12], index=pd.date_range(start='2015-01',end='2016-01',freq='M'), columns=['2015'])
data16 = pd.DataFrame([5,4,3,2,1], index=pd.date_range(start='2016-01',end='2016-06',freq='M'), columns=['2016'])
#generating column with month number
data15['month'] = data15.index.to_series().dt.month
data16['month'] = data16.index.to_series().dt.month
fig, ax = plt.subplots()
ax.plot(data15['month'], data15['2015'], label="2015")
ax.plot(data16['month'], data16['2016'], label="2016")
#setting x-ticks 1-12 with corresponding month names
ax.set_xticks(range(1, 13), [calendar.month_abbr[i] for i in range(1, 13)])
ax.legend()
plt.show()
输出:
或者,您可以创建全部设置为任意年份相应月份的第一天的日期时间对象:
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
data15 = pd.DataFrame([1,2,3,4,5,6,7,8,9,10,11,12], index=pd.date_range(start='2015-01',end='2016-01',freq='M'), columns=['2015'])
data16 = pd.DataFrame([5,4,3,2,1], index=pd.date_range(start='2016-01',end='2016-06',freq='M'), columns=['2016'])
#generating datetime objects keeping only the month
#while setting day/year to arbitrary values so that the curves align
data15['month'] = data15.index + pd.offsets.DateOffset(day=1, year=2000)
data16['month'] = data16.index + pd.offsets.DateOffset(day=1, year=2000)
fig, ax = plt.subplots()
ax.plot(data15['month'], data15['2015'], label="2015")
ax.plot(data16['month'], data16['2016'], label="2016")
#formatting monthly x-axis ticks showing only the month name
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=1))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b'))
ax.legend()
plt.show()
输出看起来是一样的,但你仍然有 datetime 对象,尽管是任意年份和日期。
假设您可能想要比较多年,您可以将第一种方法嵌入到这样的函数中:
import pandas as pd
import matplotlib.pyplot as plt
import calendar
data15 = pd.DataFrame([1,2,3,4,5,6,7,8,9,10,11,12], index=pd.date_range(start='2015-01',end='2016-01',freq='M'), columns=['2015'])
data16 = pd.DataFrame([5,4,3,2,1], index=pd.date_range(start='2016-01',end='2016-06',freq='M'), columns=['2016'])
#collecting all dataframes to plot
plot_list = [data15, data16]
fig, ax = plt.subplots()
def plot_line(df):
#this assumes that the data to plot will always be in the first column
col = df.columns[0]
ax.plot(df.index.to_series().dt.month, df[col], label=col)
for item in plot_list:
plot_line(item)
ax.set_xticks(range(1, 13), [calendar.month_abbr[i] for i in range(1, 13)])
ax.legend()
plt.show()
我想在同一个轴上绘制几年的数据。 xlim
。 MWE 是
import numpy as np
import pandas as pd
from datetime import datetime, date, timedelta
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.ticker as tkr
data15 = pd.DataFrame([1,2,3,4,5,6,7,8,9,10,11,12], index=pd.date_range(start='2015-01',end='2016-01',freq='M'), columns=['2015'])
data16 = pd.DataFrame([5,4,3,2,1], index=pd.date_range(start='2016-01',end='2016-06',freq='M'), columns=['2016'])
data15['month'] = data15.index.to_series().dt.strftime('%b')
data16['month'] = data16.index.to_series().dt.strftime('%b')
ax = data16.plot(x='month', y='2016')
ax = data15.plot(x='month', y='2015', ax=ax)
ax.xaxis.set_major_locator(mdates.DayLocator(interval=1))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b'))
plt.setp(ax.get_xticklabels()[::2], visible=False)
ax.set_xlim(data16.month[0], data16.month[-1])
plt.show()
不管我怎么改都只想显示前两个数据点xlim
。我该如何解决这个问题?
没有set_xlim
的图是
所以 ax.set_xlim(data16.month[0], data16.month[-1])
行应该只显示 Jan
和 May
之间的点。
目前还不清楚数据帧的条件是什么,但将 pandas matplotlib 便利包装器与 higher-end matplotlib 函数混合使用通常会产生问题。假设每个数据帧恰好存在一个每月数据点,您可以提取月份编号并使用月份名称重新标记 x-axis:
import pandas as pd
import matplotlib.pyplot as plt
import calendar
data15 = pd.DataFrame([1,2,3,4,5,6,7,8,9,10,11,12], index=pd.date_range(start='2015-01',end='2016-01',freq='M'), columns=['2015'])
data16 = pd.DataFrame([5,4,3,2,1], index=pd.date_range(start='2016-01',end='2016-06',freq='M'), columns=['2016'])
#generating column with month number
data15['month'] = data15.index.to_series().dt.month
data16['month'] = data16.index.to_series().dt.month
fig, ax = plt.subplots()
ax.plot(data15['month'], data15['2015'], label="2015")
ax.plot(data16['month'], data16['2016'], label="2016")
#setting x-ticks 1-12 with corresponding month names
ax.set_xticks(range(1, 13), [calendar.month_abbr[i] for i in range(1, 13)])
ax.legend()
plt.show()
输出:
或者,您可以创建全部设置为任意年份相应月份的第一天的日期时间对象:
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
data15 = pd.DataFrame([1,2,3,4,5,6,7,8,9,10,11,12], index=pd.date_range(start='2015-01',end='2016-01',freq='M'), columns=['2015'])
data16 = pd.DataFrame([5,4,3,2,1], index=pd.date_range(start='2016-01',end='2016-06',freq='M'), columns=['2016'])
#generating datetime objects keeping only the month
#while setting day/year to arbitrary values so that the curves align
data15['month'] = data15.index + pd.offsets.DateOffset(day=1, year=2000)
data16['month'] = data16.index + pd.offsets.DateOffset(day=1, year=2000)
fig, ax = plt.subplots()
ax.plot(data15['month'], data15['2015'], label="2015")
ax.plot(data16['month'], data16['2016'], label="2016")
#formatting monthly x-axis ticks showing only the month name
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=1))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b'))
ax.legend()
plt.show()
输出看起来是一样的,但你仍然有 datetime 对象,尽管是任意年份和日期。
假设您可能想要比较多年,您可以将第一种方法嵌入到这样的函数中:
import pandas as pd
import matplotlib.pyplot as plt
import calendar
data15 = pd.DataFrame([1,2,3,4,5,6,7,8,9,10,11,12], index=pd.date_range(start='2015-01',end='2016-01',freq='M'), columns=['2015'])
data16 = pd.DataFrame([5,4,3,2,1], index=pd.date_range(start='2016-01',end='2016-06',freq='M'), columns=['2016'])
#collecting all dataframes to plot
plot_list = [data15, data16]
fig, ax = plt.subplots()
def plot_line(df):
#this assumes that the data to plot will always be in the first column
col = df.columns[0]
ax.plot(df.index.to_series().dt.month, df[col], label=col)
for item in plot_list:
plot_line(item)
ax.set_xticks(range(1, 13), [calendar.month_abbr[i] for i in range(1, 13)])
ax.legend()
plt.show()