Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating tables in matplotlib

I'm trying to make a table using matplotlib and I've managed to get my data in but I'm struggling with the final formatting. I need to edit the size of the figure to include all my data as some is getting chopped off. Here is my current code:

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")

Which creates a table like so (I'm not completely sure how to get ride of the lines through certain rows either): enter image description here

Any help is greatly appreciated!

like image 260
Jsg91 Avatar asked Jun 21 '13 10:06

Jsg91


2 Answers

You should be able to solve your problems doing the following:

  • Figure size (edit):

    • Measure how high and wide is a cell (e.g. hcell=0.3, wcell=1)
    • Get/know the number of rows and columns (in your case len(clust_data)+1 and 3)
    • create the figure with the correct size (you might want some extra padding)

      fig = plt.figure(figsize=(3*wcell+wpad, nrows*hcell+hpad))
      
  • The lines within the two rows are the axes spines.

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

    just hide the axis labels and ticks, not the axes spines. You have to hide them or colour them in white

see full solution below


In any case: it looks to me that you are doing a whole lot of useless operations. From your piece of code it seems to me that clust_data is already a list of lists with the correct shape and that cellText after being filled is going to be the same of clust_data.
Furthermore, try not to mix the OO and pyplot interface of matplotlib.

The following code should be equivalent to yours

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")

Edit: full solution

Convoluted way

You have to hide the axes spines (e.g. setting their color white) and give them low zorder then add the table with higher 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")

Simple way (credit @JoeKington)

Just switch off the axis

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")
like image 137
Francesco Montesano Avatar answered Sep 24 '22 23:09

Francesco Montesano


It is just a curiosity. You can print your table from latex. If you try this code,

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()

you will see a beatifull table in the top left of the plot. Now, it is almost straight-forward to write a function to transform your data into a string like the previous latex table.

like image 30
Alejandro Avatar answered Sep 20 '22 23:09

Alejandro