CodingCat
CodingCat

Reputation: 5411

Matplotlib table: individual column width

Is there a way to specify the width of individual columns in a matplotlib table?

The first column in my table contains just 2-3 digit IDs, and I'd like this column to be smaller than the others, but I can't seem to get it to work.

Let's say I have a table like this:

import matplotlib.pyplot as plt

fig = plt.figure()
table_ax = fig.add_subplot(1,1,1)

table_content = [["1", "Daisy", "ill"],
                 ["2", "Topsy", "healthy"]]
table_header = ('ID', 'Name','Status')

the_table = table_ax.table(cellText=table_content, loc='center', colLabels=table_header, cellLoc='left')

fig.show()

(Never mind the weird cropping, it doesn't happen in my real table.)

What I've tried is this:

prop = the_table.properties()
cells = prop['child_artists']

for cell in cells:
    text = cell.get_text()
    if text == "ID":
        cell.set_width(0.1)
    else:
        try:
            int(text)
            cell.set_width(0.1)
        except TypeError:
            pass

The above code seems to have zero effect - the columns are still all equally wide. (cell.get_width() returns 0.3333333333, so I would think that width is indeed cell-width... so what am I doing wrong?

Any help would be appreciated!

Upvotes: 4

Views: 10460

Answers (3)

Morlord
Morlord

Reputation: 85

Just for completion. The column header starts with (0,0) ... (0, n-1). The row header starts with (1,-1) ... (n,-1).

                  ---------------------------------------------
                  | ColumnHeader (0,0)  | ColumnHeader (0,1)  |
                  ---------------------------------------------
rowHeader (1,-1)  | Value  (1,0)        | Value  (1,1)        |
                   --------------------------------------------
rowHeader (2,-1)  | Value  (2,0)        | Value  (2,1)        |
                   --------------------------------------------

The code:

for key, cell in the_table.get_celld().items():
    print (str(key[0])+", "+ str(key[1])+"\t"+str(cell.get_text()))

Upvotes: 5

OHo
OHo

Reputation: 136

I've been searching the web over and over again looking for similar probelm sollutions. I've found some answers and used them, but I didn't find them quite straight forward. By chance I just found the table method get_celld when simply trying different table methods. By using it you get a dictionary where the keys are tuples corresponding to table coordinates in terms of cell position. So by writing

cellDict=the_table.get_celld()
cellDict[(0,0)].set_width(0.1)

you will simply adress the upper left cell. Now looping over rows or columns will be fairly easy.

A bit late answer, but hopefully others may be helped.

Upvotes: 12

ev-br
ev-br

Reputation: 26080

Condition text=="ID" is always False, since cell.get_text() returns a Text object rather than a string:

for cell in cells:
    text = cell.get_text()
    print text, text=="ID"  # <==== here
    if text == "ID":
        cell.set_width(0.1)
    else:
        try:
            int(text)
            cell.set_width(0.1)
        except TypeError:
            pass

On the other hand, addressing the cells directly works: try cells[0].set_width(0.5).

EDIT: Text objects have an attribute get_text() themselves, so getting down to a string of a cell can be done like this:

    text = cell.get_text().get_text() # yup, looks weird
    if text == "ID":

Upvotes: 1

Related Questions