0

I'm trying to make a table with a dimension of Nx7 where N is a variable.
It is quite challenging to make a proper size of table via matplotlib.
I wanna put it on the center of the plot with a title which is located just above the table.
Here's my code

data = [
   ['A', 'B', 'C', 'D', 'E', 'F'],
   ['100%', '200%', 'O', 'X', '1.2%', '100', '200'],
   ['100%', '200%', 'O', 'X', '1.2%', '100', '200'],
   ['100%', '200%', 'O', 'X', '1.2%', '100', '200'],
   ['100%', '200%', 'O', 'X', '1.2%', '100', '200'],
   ['100%', '200%', 'O', 'X', '1.2%', '100', '200']]

fig, ax1 = plt.subplots(dpi=200)

column_headers = data.pop(0)
row_headers = [x.pop(0) for x in data]
rcolors = np.full(len(row_headers), 'linen')
ccolors = np.full(len(column_headers), 'lavender')

cell_text = []
for row in data:
    cell_text.append([x for x in row])

table = ax1.table(cellText=cell_text,
                  cellLoc='center',
                  rowLabels=row_headers,
                  rowColours=rcolors,
                  rowLoc='center',
                  colColours=ccolors,
                  colLabels=column_headers,
                  loc='center')
fig.tight_layout()

table.scale(1, 0.5)
table.set_fontsize(16)
# Hide axes
ax1.get_xaxis().set_visible(False)
ax1.get_yaxis().set_visible(False)

# Add title
ax1.set_title('{}\n({})'.format(title, subtitle), weight='bold', size=14, color='k')

fig.tight_layout()
plt.savefig(filename)

In my code, there are several problems.

  1. The title is overlapped on the table.
  2. The whole figure is somehow right-side shifted from the center. (Left side of resulting image is filled with empty space)
  3. The size of text in the table is not 16. (much much smaller than the title)
Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Suho Cho
  • 575
  • 1
  • 7
  • 14
  • Does this answer your question? [Matplotlib table formatting column width](https://stackoverflow.com/questions/40453531/matplotlib-table-formatting-column-width) – Joshua Foo Jan 17 '21 at 14:44
  • Are you running a recent version of matplotlib (current is `3.3.3`)? – JohanC Jan 17 '21 at 17:20
  • @JoshuaFooJF It helps at some part of problems. Thanks for good reference – Suho Cho Jan 18 '21 at 00:22

1 Answers1

2

Here is some code to draw the table.

Some remarks:

  • The support for table in matplotlib is rather elementary. It is mostly meant to add some text in table form on an existing plot.
  • Using .pop() makes the code difficult to reason about. In Python, usually new lists are created starting from the given lists.
  • As the adequate size of the plot highly depends on the number of rows, a possibility is to calculate it as some multiple. The exact values depend on the complete table, it makes sense to experiment a bit. The values below seem to work well for the given example data.
  • dpi and tight bounding box can be set as parameters to savefig().
  • Different matplotlib versions might behave slightly different. The code below is tested with matplotlib 3.3.3.
import numpy as np
import matplotlib.pyplot as plt

N = 10
data = [['A', 'B', 'C', 'D', 'E', 'F']] + [['100%', '200%', 'O', 'X', '1.2%', '100', '200']] * N
column_headers = data[0]
row_headers = [row[0] for row in data[1:]]
cell_text = [row[1:] for row in data[1:]]

fig, ax1 = plt.subplots(figsize=(10, 2 + N / 2.5))

rcolors = np.full(len(row_headers), 'linen')
ccolors = np.full(len(column_headers), 'lavender')

table = ax1.table(cellText=cell_text,
                  cellLoc='center',
                  rowLabels=row_headers,
                  rowColours=rcolors,
                  rowLoc='center',
                  colColours=ccolors,
                  colLabels=column_headers,
                  loc='center')
table.scale(1, 2)
table.set_fontsize(16)
ax1.axis('off')
title = "demo title"
subtitle = "demo subtitle"
ax1.set_title(f'{title}\n({subtitle})', weight='bold', size=14, color='k')

plt.savefig("demo_table.png", dpi=200, bbox_inches='tight')

example figure

JohanC
  • 71,591
  • 8
  • 33
  • 66