Python 如何向matplotllib条形图的x轴添加第二行标签

Python 如何向matplotllib条形图的x轴添加第二行标签,python,pandas,matplotlib,Python,Pandas,Matplotlib,我有一个Pandas数据框,它使用“季度”和“年”记录时间,如下所示: import pandas as pd myDF = pd.DataFrame({'quarter':['Q1','Q2','Q3','Q4','Q1','Q2','Q3','Q4','Q1','Q2','Q3','Q4'], 'year':[2018,2018,2018,2018,2019,2019,2019,2019,2020,2020,2020,2020],

我有一个Pandas数据框,它使用“季度”和“年”记录时间,如下所示:

import pandas as pd

myDF = pd.DataFrame({'quarter':['Q1','Q2','Q3','Q4','Q1','Q2','Q3','Q4','Q1','Q2','Q3','Q4'],
                     'year':[2018,2018,2018,2018,2019,2019,2019,2019,2020,2020,2020,2020],
                     'data':[2,3,4,3,4,5,6,5,6,7,8,7,8,9,10,9]})
这看起来像:

    year quarter  data
0   2018      Q1     2
1   2018      Q2     3
2   2018      Q3     4
3   2018      Q4     3
4   2019      Q1     4
5   2019      Q2     5
6   2019      Q3     6
7   2019      Q4     5
8   2020      Q1     6
9   2020      Q2     7
10  2020      Q3     8
11  2020      Q4     7
我可以使用以下方法绘制“数据”与“季度”的条形图:

fig = plt.figure()
ax = fig.add_subplot(111)
rects = ax.bar(np.arange(len(myDF['quarter'])),
               myDF['data'],
               width = 0.8,
               )
ax.set_xticks(np.arange(len(myDF['quarter'])))
ax.set_xticklabels(myDF['quarter'])

plt.show()
该图显示为:


我希望能够在给出年份的x轴上额外添加一行,或者将年份向左对齐,使年份值显示在Q1的正下方,或者将年份值对齐,使年份值显示在Q2和Q3之间的中点下方。

在这种情况下,最简单的方法是更改标签,将年份添加到每个
Q1

fig,ax=plt.subplot()
矩形=ax.bar(np.arange(len(myDF['quarter'])),myDF['data'],宽度=0.8)
ax.set\u xticks(np.arange(len(myDF['quarter')))
ax.set_xticklabels([f'{q}\n{y%100:02d}如果q='Q1'其他q
对于邮政编码中的q,y(myDF['quarter',myDF['year']))
plt.show()

在这种情况下,最简单的方法是更改标签,将年份添加到每个
Q1

fig,ax=plt.subplot()
矩形=ax.bar(np.arange(len(myDF['quarter'])),myDF['data'],宽度=0.8)
ax.set\u xticks(np.arange(len(myDF['quarter')))
ax.set_xticklabels([f'{q}\n{y%100:02d}如果q='Q1'其他q
对于邮政编码中的q,y(myDF['quarter',myDF['year']))
plt.show()

经过进一步调查,我找到了一个适合我的解决方案。我将季度号(即第一季度、第二季度、第三季度等)作为主要节拍的标签,但也添加了年份作为次要节拍的标签

完整的解决方案是:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

myDF = pd.DataFrame({'quarter':['Q1','Q2','Q3','Q4','Q1','Q2','Q3','Q4','Q1','Q2','Q3','Q4'],
                     'year':[2018,2018,2018,2018,2019,2019,2019,2019,2020,2020,2020,2020],
                     'data':[2,3,4,3,4,5,6,5,6,7,8,7]})
print(myDF[['year','quarter','data']])

fig = plt.figure()
ax = fig.add_subplot(111)
rects = ax.bar(np.arange(len(myDF['quarter'])),
               myDF['data'],
               width = 0.8,
               )

# Set major xticks and xlabels - Quarter number
# ----------------------------
ax.xaxis.set_major_locator(ticker.FixedLocator(np.arange(0,len(myDF.index))))
ax.xaxis.set_major_formatter(ticker.FixedFormatter(myDF['quarter']))
ax.tick_params(which='major', length=5)

# Set minor xticks and xlabels - Year
# ----------------------------
# Use list comprehension to find average of index for each subsequent group of 4 items.
# Could use FuncFormatter to define function to calculate position of Year values.
ax.xaxis.set_minor_locator(ticker.FixedLocator([np.mean(myArr[i:i+4]) for i in range(0,len(np.arange(0,len(myDF.index))),4)]))
ax.tick_params(which='minor', pad=30)
ax.xaxis.set_minor_formatter(ticker.FixedFormatter(myDF['year'].unique()))
# Change font used to display years
for tick in ax.xaxis.get_minor_ticks():
    tick.label.set_fontsize(14)
    tick.label.set_fontweight('bold')

plt.show()
在上面的例子中,我使用列表理解来计算4个四分之一区块的平均值(例如,位置0、1、2和3的平均值产生1.5,等等)。精确定义小记号出现位置的代码可以根据需要简单或复杂,以生成所需的值

生成的图形如下所示:

    year quarter  data
0   2018      Q1     2
1   2018      Q2     3
2   2018      Q3     4
3   2018      Q4     3
4   2019      Q1     4
5   2019      Q2     5
6   2019      Q3     6
7   2019      Q4     5
8   2020      Q1     6
9   2020      Q2     7
10  2020      Q3     8
11  2020      Q4     7

经过进一步调查,我找到了一个适合我的解决方案。我将季度号(即第一季度、第二季度、第三季度等)作为主要节拍的标签,但也添加了年份作为次要节拍的标签

完整的解决方案是:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

myDF = pd.DataFrame({'quarter':['Q1','Q2','Q3','Q4','Q1','Q2','Q3','Q4','Q1','Q2','Q3','Q4'],
                     'year':[2018,2018,2018,2018,2019,2019,2019,2019,2020,2020,2020,2020],
                     'data':[2,3,4,3,4,5,6,5,6,7,8,7]})
print(myDF[['year','quarter','data']])

fig = plt.figure()
ax = fig.add_subplot(111)
rects = ax.bar(np.arange(len(myDF['quarter'])),
               myDF['data'],
               width = 0.8,
               )

# Set major xticks and xlabels - Quarter number
# ----------------------------
ax.xaxis.set_major_locator(ticker.FixedLocator(np.arange(0,len(myDF.index))))
ax.xaxis.set_major_formatter(ticker.FixedFormatter(myDF['quarter']))
ax.tick_params(which='major', length=5)

# Set minor xticks and xlabels - Year
# ----------------------------
# Use list comprehension to find average of index for each subsequent group of 4 items.
# Could use FuncFormatter to define function to calculate position of Year values.
ax.xaxis.set_minor_locator(ticker.FixedLocator([np.mean(myArr[i:i+4]) for i in range(0,len(np.arange(0,len(myDF.index))),4)]))
ax.tick_params(which='minor', pad=30)
ax.xaxis.set_minor_formatter(ticker.FixedFormatter(myDF['year'].unique()))
# Change font used to display years
for tick in ax.xaxis.get_minor_ticks():
    tick.label.set_fontsize(14)
    tick.label.set_fontweight('bold')

plt.show()
在上面的例子中,我使用列表理解来计算4个四分之一区块的平均值(例如,位置0、1、2和3的平均值产生1.5,等等)。精确定义小记号出现位置的代码可以根据需要简单或复杂,以生成所需的值

生成的图形如下所示:

    year quarter  data
0   2018      Q1     2
1   2018      Q2     3
2   2018      Q3     4
3   2018      Q4     3
4   2019      Q1     4
5   2019      Q2     5
6   2019      Q3     6
7   2019      Q4     5
8   2020      Q1     6
9   2020      Q2     7
10  2020      Q3     8
11  2020      Q4     7

yearlocator可能会有所帮助。你检查过这个吗?yearlocator可以帮上忙。你检查过这个吗?谢谢你的回复。这个解决方案在某些情况下当然可以工作,但我希望在第二行标签出现的位置上有更多的灵活性。谢谢您的回复。这个解决方案在某些情况下当然可以工作,但我希望在第二行标签出现的位置上有更多的灵活性。