在Matplotlib中创建表格

16

我正在尝试使用matplotlib制作一张表格,我的数据已经导入成功,但是我在最后的格式调整上遇到了些问题。我需要编辑图形的大小以包含所有数据,因为有些被截断了。这是我当前的代码:

for struct, energy, density in clust_data:
    fig=plt.figure()
    ax = plt.gca()
    ax.xaxis.set_visible(False)
    ax.yaxis.set_visible(False)
    colLabels=("Structure", "Energy", "Density")
    rows=len(clust_data)
    cellText=[]
    for row in clust_data:
        cellText.append(row)
    the_table = ax.table(cellText=cellText,
              colLabels=colLabels,
              loc='center')
    plt.savefig("table.png")

这将创建一个类似于下面的表格(我不是完全确定如何去掉某些行的线): 在此输入图片描述

非常感谢您的帮助!


1
你正在对同一个列表(clust_data)执行双重循环,而外部循环除了创建和保存 len(clust_data) 之外没有做任何事情:第一个for循环是笔误吗? - Francesco Montesano
2个回答

13

按照以下步骤,您应该能够解决问题:

  • 图形大小 (编辑):

    • 测量单元格的高度和宽度(例如:hcell=0.3wcell=1
    • 获取/知道行数和列数(在您的情况下为len(clust_data)+1和3)
    • 使用正确的大小创建图片(您可能需要一些额外的填充)

fig = plt.figure(figsize=(3*wcell+wpad, nrows*hcell+hpad))
  • 两行之间的线是坐标轴脊柱。

  • ax.xaxis.set_visible(False)
    ax.yaxis.set_visible(False)
    

    仅隐藏轴标签和刻度,不要隐藏轴脊线。您必须隐藏它们或将它们涂成白色。

    完整解决方案请见下文


    无论如何:在我看来,你正在进行许多无用的操作。从你的代码片段中,我觉得clust_data已经是一个具有正确形状的列表,而填充后的cellText将与clust_data相同。
    此外,尽量不要混合使用matplotlib的OO和pyplot接口。

    以下代码应该与您的代码等效

    fig=plt.figure()
    ax = fig.add_subplot(111)
    ax.xaxis.set_visible(False)
    ax.yaxis.set_visible(False)
    colLabels=("Structure", "Energy", "Density")
    the_table = ax.table(cellText=clust_data,
              colLabels=colLabels,
              loc='center')
    plt.savefig("table.png")
    

    完整解决方案:

    复杂方式

    您需要隐藏坐标轴脊柱(例如将它们的颜色设置为白色)并给它们较低的zorder,然后添加具有更高zorder的表格。

    colLabels=("Structure", "Energy", "Density")
    nrows, ncols = len(clust_data)+1, len(colLabels)
    hcell, wcell = 0.3, 1.
    hpad, wpad = 0, 0    
    
    fig=plt.figure(figsize=(ncols*wcell+wpad, nrows*hcell+hpad))
    ax = fig.add_subplot(111)
    #remove axis ticks and labels
    ax.xaxis.set_visible(False)
    ax.yaxis.set_visible(False)
    #hide the spines
    for sp in ax.spines.itervalues():
        sp.set_color('w')
        sp.set_zorder(0)
    #do the table
    the_table = ax.table(cellText=clust_data,
              colLabels=colLabels,
              loc='center')
    #put the table in front of the axes spines 
    #for some reason zorder is not a keyword in ax.table
    the_table.set_zorder(10)
    plt.savefig("table.png")
    

    简单方法(感谢 @JoeKington)

    只需关闭轴即可。

    colLabels=("Structure", "Energy", "Density")
    nrows, ncols = len(clust_data)+1, len(colLabels)
    hcell, wcell = 0.3, 1.
    hpad, wpad = 0, 0    
    fig=plt.figure(figsize=(ncols*wcell+wpad, nrows*hcell+hpad))
    ax = fig.add_subplot(111)
    ax.axis('off')
    #do the table
    the_table = ax.table(cellText=clust_data,
              colLabels=colLabels,
              loc='center')
    plt.savefig("table.png")
    

    感谢您的大力帮助!这解决了脊柱问题,但仍未包括我的整个数据集,表格上下应该有行。编辑:clust_data只是一个列表,每个项目包含3个值(x、y、z)。 - Jsg91
    6
    @FrancescoMontesano - 你不需要费太多周折来隐藏东西。你可以用ax.axis('off')来替换你示例代码的一半,这样就可以省略掉所有的set_visible(False)set_color('w')set_zorder(...) - Joe Kington
    1
    所以在表格上方和下方有很多空白,我必须放大才能看清任何细节。 - Jsg91
    3
    尝试使用fig.savefig('table.png', bbox_inches='tight', bbox_extra_artists=[table])来消除空白部分。(这也将裁剪图像。如果表格超出了图形边界,则保存的图像将显示整张表格,而不仅仅是通过plt.show()所看到的部分。) - Joe Kington
    1
    @FrancescoMontesano - 谢谢!只是让您知道,Simple Way 代码中有一个拼写错误:len(colLables) 应该是 len(colLabels) - Roberto
    显示剩余3条评论

    6

    这只是一个好奇心。您可以从latex打印您的表格。如果您尝试这段代码,

    import matplotlib.pyplot as plt
    import numpy as np
    
    table = r'\begin{table} \begin{tabular}{|l|l|l|}  \hline  $\alpha$      & $\beta$        & $\gamma$      \\ \hline   32     & $\alpha$ & 123    \\ \hline   200 & 321    & 50 \\  \hline  \end{tabular} \end{table}'
    plt.plot(np.arange(100))
    plt.text(10,80,table, size=50)
    plt.show()
    

    在图表的左上方,您将看到一个漂亮的表格。现在,编写一个函数将您的数据转换为类似于以前的latex表格的字符串几乎是直截了当的。


    4
    最小的异议-我认为你需要添加以下代码:import matplotlib as mpl; mpl.rc('text', usetex=True),以确保LaTeX渲染。不错的解决方案! - CompEcon
    是的,没错。虽然我鼓励修改matplotlibrc文件中的这些行。 - Alejandro
    2
    不幸的是,我经常发现自己处于这样一种情况:我向需要“只需运行即可正常工作”的用户发送单个代码文件(因此在我的代码中,还有一个开关可以完全不使用latex,如果他们的机器没有安装它的话)。这就是生活吧... - CompEcon

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接