2

I am struggling to left/right align text properly without having wasted space in the columns. The same col widths are being used for center/left/right:

  1. Center aligned: properly centered, ok
  2. Left aligned: wasted space on the left
  3. Even with omitting colWidths as table argument and playing around with my favorite solution the_table._autoColumns = range (-1,len (colLabels)) does not improve the situation

What am I doing wrong? Is this a bug in matplotlib?

Best Regards, René

import pandas as pd 
import matplotlib.pyplot as plt

size_x, size_y = 12, 4
fig = plt.figure (figsize=(size_x, size_y))
ax  = fig.add_subplot(111)

col_ID    = pd.Series ([ "R001", "R002", "R003", "R005", "R006", "R007" ])
col_Title = pd.Series ([ 50*"*", 10*"-", 70*"x", "R005", "R006", "R007" ])
col_x     = pd.Series ([  3,      1,      3,      4,      2,      3 ])
col_y     = pd.Series ([  4,      2,      3,      2,      4,      3 ])

legend_df = pd.DataFrame ({ "ID"    : col_ID,
                            "Title" : col_Title,
                            "X-Pos" : col_x,
                            "Y-Pos" : col_y,
                            "Value" : col_x * col_y })
rowLabels = legend_df.index
colLabels = legend_df.columns
cellText  = legend_df.values

# Center-Aligned text looks ok
the_table = plt.table (cellText=cellText, rowLabels=rowLabels, colLabels=colLabels, loc='upper center', cellLoc="center", colWidths=[0.05, 0.52, 0.05, 0.05, 0.05, 0.05])

# Bogus: Same colWidths, but left OR right aligned -> unwanted space in title column
# the_table = ax.table (cellText=cellText, rowLabels=rowLabels, colLabels=colLabels, loc='upper center', cellLoc="left", colWidths=[0.05, 0.52, 0.05, 0.05, 0.05, 0.05])

the_table.auto_set_font_size(False)
the_table.set_fontsize (8)

# Set col width automatically
# the_table._autoColumns = range (-1,len (colLabels))

ax.xaxis.set_visible (False)                                            # Grafik-Achsen ausschalten, wir wollen nur Plot
ax.yaxis.set_visible (False)
# the_table.scale(2, 2) 

plt.show()

2 Answers 2

4

Per default the cells have a 10% padding to both sides, which is useful to let the text start a bit next to the table cell border. For very large cells 10% is then too much and leads to the undesired large space.

enter image description here

To overcome this, one would need to set the padding for the column in question to a lower value, as for all other columns 10% is actually desireable. There is no built-in option to set the padding, but one may manipulate it by looping over the cells of the column and changing the respective PAD attribute.

def set_pad_for_column(col, pad=0.1):
    cells = the_table.get_celld()
    column = [cell for cell in the_table.get_celld() if cell[1] == col]
    for cell in column:
        cells[cell].PAD = pad

set_pad_for_column(col=1, pad=0.01) 

This produces a padding of 1% only for the second column (col=1).

enter image description here

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the quick response. Wouldn't it be better to have the padding value depend on the font size rather than the column width?
The way the table class is written in matplotlib, there is no way to change the padding to be font-size dependent - apart of course from subclassing the table class and the cell class and reimplementing the respective method. Are you asking my opinion on this design choice?
Maybe it is worth to open a bug in matplotlib? From my point of view a work around exists (your solution) but sane defaults/algorithms should exist so users do not have to tweak implementation internals - what is your opinion?
This is your choice. I would not call it bug-report but feature-request, but you can file that at the matplotlib issue page. Personally I would not consider this to be very urgent or necessary, but that's only my point of view, others may see it differently.
3

Equivalent to answer by ImportanceOfBeingErnest but with a shorter syntax (not as function):

 for key,cell in the_table.get_celld().items():
    if key[1]==1:                   
        cell.PAD = 0.01

The code gets the second column of the_table and changes the padding.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.