0

I would like to create a multicolumn table using Matplotlib something like the picture below.

enter image description here

How can I tweak the code below to get a table as shown above.

Currently, the code will produce something like below. enter image description here

But, this is unpleasent way of presenting a multi column table

import matplotlib
import matplotlib.pyplot as plt  # noqa
matplotlib.use ('TkAgg')
import six
import pandas as pd
import numpy as np
def render_mpl_table (data, col_width=0.1, row_height=0.1, font_size=8,
                      header_color='#40466e', row_colors=['#f1f1f2', 'w'], edge_color='w',
                      bbox=[0, 0, 1, 1], header_columns=0,
                      ax=None, **kwargs):
    # https://stackoverflow.com/a/39358752/6446053
    if ax is None:
        size = (np.array (data.shape [::-1]) + np.array ([0, 1])) * np.array ([col_width, row_height])
        fig, ax = plt.subplots (figsize=size)
        ax.axis ('off')

    mpl_table = ax.table (cellText=data.values, bbox=bbox, colLabels=data.columns, **kwargs)

    mpl_table.auto_set_font_size (False)
    mpl_table.set_fontsize (font_size)

    for k, cell in six.iteritems (mpl_table._cells):
        cell.set_edgecolor (edge_color)
        if k [0] == 0 or k [1] < header_columns:
            cell.set_text_props (weight='bold', color='w')
            cell.set_facecolor (header_color)
            cell.get_text ().set_rotation (90)
            cell.set_height (1)
        else:
            cell.set_facecolor (row_colors [k [0] % len (row_colors)])
    return ax


df = pd.DataFrame ({'Label': ['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd', 'd'],
                    'Month': ['Type  1', 'Type  1', 'Type 2', 'Type 2', 'Type 3',
                              'Type  1', 'Type 3', 'Type  1', 'Type 2'],
                    'Activity': ['cc', 'cc', 'tt', 'cc', 'tt', 'tt', 'bb', 'bb', 'cc', ]})
tt = pd.crosstab (index=[df ['Activity']], columns=[df ['Label'], df ['Month']], margins=True)


tab_me = render_mpl_table (tt)
plt.show ()

Appreciate for any hint or link.

mpx
  • 3,081
  • 2
  • 26
  • 56
  • 1
    Matplotlib is not a typesetting engine, in particular **Matplotlib does not support the idea of colspans** etc. If you want to fake colspans, you should start from [this answer](https://stackoverflow.com/a/53573651/2749397). Warning, it seems a lot of work. – gboffi Sep 14 '20 at 10:03
  • Thanks @gboffi. Do you any alternative libraries that achieve the intended objective? – mpx Sep 14 '20 at 13:54
  • Under threat of being fired I'd probably try to convince Python to output a string of LaTeX commands, convert LaTeX's output to a PNG and insert/overlay it into the figure. Still a lot of work. I'm afraid I don't know of a simple straightforward solution. – gboffi Sep 14 '20 at 16:38

0 Answers0