简体   繁体   English

如何使用 matplotlib.pyplot 在条形图和数据表之间创建空间?

[英]How to create space between bar chart and data table using matplotlib.pyplot?

I have been searching for hours how to add space between a bar chart and a table using matplotlib.pyplot but I haven't found a solution on how to display the layout properly.我一直在搜索如何使用 matplotlib.pyplot 在条形图和表格之间添加空间,但我还没有找到有关如何正确显示布局的解决方案。 Currently the top of the table collides with the bar chart x axis header and the bottom of the table is out of the figure.目前,表格顶部与条形图 x 轴标题相撞,表格底部不在图中。 I have tried making the figure bigger with figsize , I have tried using bbox , subplots_adjust , plt.tight_layout() but none works.我曾尝试做图用更大figsize ,我已经尝试使用bboxsubplots_adjustplt.tight_layout()但没有作品。 Any help is appreciated.任何帮助表示赞赏。

在此处输入图片说明

def plot_bar(df, *args):
    df = pd.DataFrame([{'OPEN': 4, 'CLOSED': 139, 'DATE': '2019-01-01'}, {'OPEN': 0, 'CLOSED': 139, 'DATE': '2019-02-01'}, {'OPEN': 1, 'CLOSED': 124, 'DATE': '2019-03-01'}, {'OPEN': 4, 'CLOSED': 127, 'DATE': '2019-04-01'}, {'OPEN': 1, 'CLOSED': 84, 'DATE': '2019-05-01'}, {'OPEN': 6, 'CLOSED': 113, 'DATE': '2019-06-01'}, {'OPEN': 0, 'CLOSED': 123, 'DATE': '2019-07-01'}, {'OPEN': 2, 'CLOSED': 109, 'DATE': '2019-08-01'}, {'OPEN': 0, 'CLOSED': 107, 'DATE': '2019-09-01'}, {'OPEN': 7, 'CLOSED': 119, 'DATE': '2019-10-01'}, {'OPEN': 2, 'CLOSED': 82, 'DATE': '2019-11-01'}, {'OPEN': 4, 'CLOSED': 83, 'DATE': '2019-12-01'}, {'OPEN': 12, 'CLOSED': 112, 'DATE': '2020-01-01'}, {'OPEN': 10, 'CLOSED': 89, 'DATE': '2020-02-01'}, {'OPEN': 31, 'CLOSED': 64, 'DATE': '2020-03-01'}])
    df["DATE"] = pd.to_datetime(df["DATE"])
    df['DATE'] = df['DATE'].apply(lambda x: [x.month, x.year])
    df['DATE'] = df['DATE'].apply(lambda x: f'{calendar.month_abbr[x[0]]}-{x[1]}')

    ax = df.plot.bar(x=args[0]['x'], y=args[0]['y'], figsize=(15, 7))
    for i, v in enumerate(df['OPEN']):
        ax.text(i - .20, v + 1, str(v), color='blue', fontweight='bold')
    for i, v in enumerate(df['CLOSED']):
        ax.text(i - .20, v + 1, str(v), color='orange', fontweight='bold')

    plt.title('Open vs Closed Tickets')
    plt.xlabel('Time')
    plt.ylabel('Tickets')

    table_columns = df['DATE'].values.tolist()
    open = df['OPEN'].values.tolist()
    closed = df['CLOSED'].values.tolist()
    table_data = [open, closed]
    table_rows = df.columns.values.tolist()[0:2]
    plt.table(cellText=table_data, rowLabels=table_rows, colLabels=table_columns, loc='bottom',
              bbox=[0, -0.250, 1, 0.2])

    plt.tight_layout()

    plt.show()

    return

Answering Diziet Asahi: I made those 2 changes but my table somehow is still cut in half man this is so frustrating.回答 Diziet Asahi:我做了那 2 个更改,但不知何故我的桌子仍然被切成两半,这太令人沮丧了。

在此处输入图片说明

One possible issue is that you have to use plt.subplots_adjust(bottom=xxx) after tight_layout() (otherwise tight_layout will undo what you did with subplots_adjust).一个可能的问题是您必须在plt.subplots_adjust(bottom=xxx)之后使用plt.subplots_adjust(bottom=xxx) tight_layout() (否则tight_layout 将撤消您对 subplots_adjust 所做的操作)。 This will change the size of the plot and make more room for the table below.这将改变绘图的大小并为下表腾出更多空间。 Increase the xxx value to suit your need, the value is given in fraction of the figure, so bottom=0.2 would locate the bottom of the plot at 20% of the figure height.增加xxx值以满足您的需要,该值以图形的分数给出,因此bottom=0.2会将图的bottom=0.2定位在图形高度的 20% 处。

The other issue is that you are using plt.table() which was made to have the table "stick" to the axes.另一个问题是您使用的plt.table()是为了让表格“粘”在轴上。 If you place the table below the axes, then it's basically supposed to replace the x-axis labels.如果您将表格放在轴下方,那么它基本上应该替换 x 轴标签。 But you have to chose between using loc= (automatic placement) or bbox= (manual placement).但是您必须在使用loc= (自动放置)或bbox= (手动放置)之间进行选择。 You cannot use both.您不能同时使用两者。

Here is the results of doing those two things:这是做这两件事的结果:

import calendar
df = pd.DataFrame([{'OPEN': 4, 'CLOSED': 139, 'DATE': '2019-01-01'}, {'OPEN': 0, 'CLOSED': 139, 'DATE': '2019-02-01'}, {'OPEN': 1, 'CLOSED': 124, 'DATE': '2019-03-01'}, {'OPEN': 4, 'CLOSED': 127, 'DATE': '2019-04-01'}, {'OPEN': 1, 'CLOSED': 84, 'DATE': '2019-05-01'}, {'OPEN': 6, 'CLOSED': 113, 'DATE': '2019-06-01'}, {'OPEN': 0, 'CLOSED': 123, 'DATE': '2019-07-01'}, {'OPEN': 2, 'CLOSED': 109, 'DATE': '2019-08-01'}, {'OPEN': 0, 'CLOSED': 107, 'DATE': '2019-09-01'}, {'OPEN': 7, 'CLOSED': 119, 'DATE': '2019-10-01'}, {'OPEN': 2, 'CLOSED': 82, 'DATE': '2019-11-01'}, {'OPEN': 4, 'CLOSED': 83, 'DATE': '2019-12-01'}, {'OPEN': 12, 'CLOSED': 112, 'DATE': '2020-01-01'}, {'OPEN': 10, 'CLOSED': 89, 'DATE': '2020-02-01'}, {'OPEN': 31, 'CLOSED': 64, 'DATE': '2020-03-01'}])
df["DATE"] = pd.to_datetime(df["DATE"])
df['DATE'] = df['DATE'].apply(lambda x: [x.month, x.year])
df['DATE'] = df['DATE'].apply(lambda x: f'{calendar.month_abbr[x[0]]}-{x[1]}')

ax = df.plot.bar(x='DATE', y=['OPEN','CLOSED'], figsize=(15, 7))
for i, v in enumerate(df['OPEN']):
    ax.text(i - .20, v + 1, str(v), color='blue', fontweight='bold')
for i, v in enumerate(df['CLOSED']):
    ax.text(i - .20, v + 1, str(v), color='orange', fontweight='bold')

plt.title('Open vs Closed Tickets')
plt.ylabel('Tickets')

#remove all x-labels since the table will be used instead
plt.xlabel('')
plt.xticks([])


table_columns = df['DATE'].values.tolist()
open = df['OPEN'].values.tolist()
closed = df['CLOSED'].values.tolist()
table_data = [open, closed]
table_rows = df.columns.values.tolist()[0:2]
plt.table(cellText=table_data, rowLabels=table_rows, colLabels=table_columns, loc='bottom')

plt.tight_layout()
plt.subplots_adjust(bottom=0.1)

plt.show()

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM