如何在离散轴上排序刻度标签(0 索引像条形图)
How to order the tick labels on a discrete axis (0 indexed like a bar plot)
我有一个包含此数据的数据框,想用 x 轴标签为月的条形图绘制它
import pandas as pd
data = {'Birthday': ['1900-01-31', '1900-02-28', '1900-03-31', '1900-04-30', '1900-05-31', '1900-06-30', '1900-07-31', '1900-08-31', '1900-09-30', '1900-10-31', '1900-11-30', '1900-12-31'],
'Players': [32, 25, 27, 19, 27, 18, 18, 21, 23, 21, 26, 23]}
df = pd.DataFrame(data)
Birthday Players
1900-01-31 32
1900-02-28 25
1900-03-31 27
1900-04-30 19
1900-05-31 27
1900-06-30 18
1900-07-31 18
1900-08-31 21
1900-09-30 23
1900-10-31 21
1900-11-30 26
1900-12-31 23
这就是我的
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
fig = plt.figure(figsize=(12, 7))
locator = mdates.MonthLocator()
fmt = mdates.DateFormatter('%b')
X = plt.gca().xaxis
X.set_major_locator(locator)
X.set_major_formatter(fmt)
plt.bar(month_df.index, month_df.Players, color = 'maroon', width=10)
但结果是这样的,标签从二月开始而不是一月
我不熟悉 matplotlib.dates,但因为您使用的是 pandas,所以有一些简单的方法可以使用 pandas.
来完成您需要的操作
这是我的代码:
import pandas as pd
import calendar
from matplotlib import pyplot as plt
# data
data = {'Birthday': ['1900-01-31', '1900-02-28', '1900-03-31', '1900-04-30', '1900-05-31', '1900-06-30', '1900-07-31', '1900-08-31', '1900-09-30', '1900-10-31', '1900-11-30', '1900-12-31'],
'Players': [32, 25, 27, 19, 27, 18, 18, 21, 23, 21, 26, 23]}
df = pd.DataFrame(data)
# convert column to datetime
df["Birthday"] = pd.to_datetime(df["Birthday"], format="%Y-%m-%d")
# groupby month and plot bar plot
df.groupby(df["Birthday"].dt.month).sum().plot(kind="bar", color = "maroon")
# set plot properties
plt.xlabel("Birthday Month")
plt.ylabel("Count")
plt.xticks(ticks = range(0,12) ,labels = calendar.month_name[1:])
# show plot
plt.show()
输出:
通常,matplotlib.bar 由于各种原因不能很好地处理日期时间。手动设置 x 刻度位置和标签很容易,如下所示。这是一个 fixed formatter 方便的包装函数,但它可以让您轻松控制。
#generate data
data = pd.Series({
'1900-01-31' : 32, '1900-02-28' : 25, '1900-03-31' : 27,
'1900-04-30' : 19, '1900-05-31' : 27, '1900-06-30' : 18,
'1900-07-31' : 18, '1900-08-31' : 21, '1900-09-30' : 23,
'1900-10-31' : 21, '1900-11-30' : 26, '1900-12-31' : 23,
})
#make plot
fig, ax = plt.subplots(figsize=(12, 7))
ax.bar(range(len(data)), data, color = 'maroon', width=0.5, zorder=3)
#ax.set_xticks uses a fixed locator
ax.set_xticks(range(len(data)))
#ax.set_xticklables uses a fixed formatter
ax.set_xticklabels(pd.to_datetime(data.index).strftime('%b'))
#format plot a little bit
ax.spines[['top','right']].set_visible(False)
ax.tick_params(axis='both', left=False, bottom=False, labelsize=13)
ax.grid(axis='y', color='gray', dashes=(8,3), alpha=0.5)
- 条形图 x 轴刻度位置是 0 索引,而不是日期时间
- 此解决方案适用于任何具有离散轴的图(例如条形图、历史图、热图等)。
- 类似于此answer,最简单的解决方案如下:
- 如果
str
列已经存在则跳到第 3 步
- 使用
pd.to_datetime
将 'Birthday'
列转换为 datetime dtype
- 将缩写的月份名称提取到单独的列中
- 使用
pd.Categorical
. The build-in calendar
模块排序列用于提供缩写月份名称的有序列表,或者可以手动输入该列表
- 使用
pandas.DataFrame.plot
绘制数据帧,它使用 matplotlib
作为默认后端
- 在
python 3.8.12
、pandas 1.3.4
、matplotlib 3.4.3
中测试
import pandas as pd
import matplotlib.pyplot as plt
from calendar import month_abbr as ma # ordered abbreviated month names
# convert the Birthday column to a datetime and extract only the date component
df.Birthday = pd.to_datetime(df.Birthday)
# create a month column
df['month'] = df.Birthday.dt.strftime('%b')
# convert the column to categorical and ordered
df.month = pd.Categorical(df.month, categories=ma[1:], ordered=True)
# plot the dataframe
ax = df.plot(kind='bar', x='month', y='Players', figsize=(12, 7), rot=0, legend=False)
- 如果有很多重复的月份,必须聚合数据,然后使用
pandas.DataFrame.groupby
合并数据并聚合一些函数,如 .mean()
或 .sum()
dfg = df.groupby('month').Players.sum()
ax = dfg.plot(kind='bar', figsize=(12, 7), rot=0, legend=False)
我有一个包含此数据的数据框,想用 x 轴标签为月的条形图绘制它
import pandas as pd
data = {'Birthday': ['1900-01-31', '1900-02-28', '1900-03-31', '1900-04-30', '1900-05-31', '1900-06-30', '1900-07-31', '1900-08-31', '1900-09-30', '1900-10-31', '1900-11-30', '1900-12-31'],
'Players': [32, 25, 27, 19, 27, 18, 18, 21, 23, 21, 26, 23]}
df = pd.DataFrame(data)
Birthday Players
1900-01-31 32
1900-02-28 25
1900-03-31 27
1900-04-30 19
1900-05-31 27
1900-06-30 18
1900-07-31 18
1900-08-31 21
1900-09-30 23
1900-10-31 21
1900-11-30 26
1900-12-31 23
这就是我的
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
fig = plt.figure(figsize=(12, 7))
locator = mdates.MonthLocator()
fmt = mdates.DateFormatter('%b')
X = plt.gca().xaxis
X.set_major_locator(locator)
X.set_major_formatter(fmt)
plt.bar(month_df.index, month_df.Players, color = 'maroon', width=10)
但结果是这样的,标签从二月开始而不是一月
我不熟悉 matplotlib.dates,但因为您使用的是 pandas,所以有一些简单的方法可以使用 pandas.
来完成您需要的操作这是我的代码:
import pandas as pd
import calendar
from matplotlib import pyplot as plt
# data
data = {'Birthday': ['1900-01-31', '1900-02-28', '1900-03-31', '1900-04-30', '1900-05-31', '1900-06-30', '1900-07-31', '1900-08-31', '1900-09-30', '1900-10-31', '1900-11-30', '1900-12-31'],
'Players': [32, 25, 27, 19, 27, 18, 18, 21, 23, 21, 26, 23]}
df = pd.DataFrame(data)
# convert column to datetime
df["Birthday"] = pd.to_datetime(df["Birthday"], format="%Y-%m-%d")
# groupby month and plot bar plot
df.groupby(df["Birthday"].dt.month).sum().plot(kind="bar", color = "maroon")
# set plot properties
plt.xlabel("Birthday Month")
plt.ylabel("Count")
plt.xticks(ticks = range(0,12) ,labels = calendar.month_name[1:])
# show plot
plt.show()
输出:
通常,matplotlib.bar 由于各种原因不能很好地处理日期时间。手动设置 x 刻度位置和标签很容易,如下所示。这是一个 fixed formatter 方便的包装函数,但它可以让您轻松控制。
#generate data
data = pd.Series({
'1900-01-31' : 32, '1900-02-28' : 25, '1900-03-31' : 27,
'1900-04-30' : 19, '1900-05-31' : 27, '1900-06-30' : 18,
'1900-07-31' : 18, '1900-08-31' : 21, '1900-09-30' : 23,
'1900-10-31' : 21, '1900-11-30' : 26, '1900-12-31' : 23,
})
#make plot
fig, ax = plt.subplots(figsize=(12, 7))
ax.bar(range(len(data)), data, color = 'maroon', width=0.5, zorder=3)
#ax.set_xticks uses a fixed locator
ax.set_xticks(range(len(data)))
#ax.set_xticklables uses a fixed formatter
ax.set_xticklabels(pd.to_datetime(data.index).strftime('%b'))
#format plot a little bit
ax.spines[['top','right']].set_visible(False)
ax.tick_params(axis='both', left=False, bottom=False, labelsize=13)
ax.grid(axis='y', color='gray', dashes=(8,3), alpha=0.5)
- 条形图 x 轴刻度位置是 0 索引,而不是日期时间
- 此解决方案适用于任何具有离散轴的图(例如条形图、历史图、热图等)。
- 类似于此answer,最简单的解决方案如下:
- 如果
str
列已经存在则跳到第 3 步
- 使用
pd.to_datetime
将 - 将缩写的月份名称提取到单独的列中
- 使用
pd.Categorical
. The build-incalendar
模块排序列用于提供缩写月份名称的有序列表,或者可以手动输入该列表 - 使用
pandas.DataFrame.plot
绘制数据帧,它使用matplotlib
作为默认后端
'Birthday'
列转换为datetime dtype
- 如果
- 在
python 3.8.12
、pandas 1.3.4
、matplotlib 3.4.3
中测试
import pandas as pd
import matplotlib.pyplot as plt
from calendar import month_abbr as ma # ordered abbreviated month names
# convert the Birthday column to a datetime and extract only the date component
df.Birthday = pd.to_datetime(df.Birthday)
# create a month column
df['month'] = df.Birthday.dt.strftime('%b')
# convert the column to categorical and ordered
df.month = pd.Categorical(df.month, categories=ma[1:], ordered=True)
# plot the dataframe
ax = df.plot(kind='bar', x='month', y='Players', figsize=(12, 7), rot=0, legend=False)
- 如果有很多重复的月份,必须聚合数据,然后使用
pandas.DataFrame.groupby
合并数据并聚合一些函数,如.mean()
或.sum()
dfg = df.groupby('month').Players.sum()
ax = dfg.plot(kind='bar', figsize=(12, 7), rot=0, legend=False)