Thomas909
Thomas909

Reputation: 147

Tabular text in matplotlib text box

I'm trying to display some statistics in a matplotlib text box in a tabular format.

Getting the text box to display works fine, and tabularizing data outside a plot with print statements using string formatting align operands ('>', '<') works fine, but once I wrap the formatted strings in ax.text(), the alignment seems to get ignored.

For example:

import matplotlib.pyplot as plt
import numpy as np

def plot_histo(data, stats):
    fig, ax = plt.subplots()
    n, bins, patches = plt.hist(data, bins=16, alpha=0.5)
    props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
    ax.text(0.8, 0.85, stats, transform=ax.transAxes, bbox=props)
    plt.show()

data = np.random.normal(size=100)
stats = '\n'.join([
        '{:<8}{:>4}'.format('n:', len(data)),
        '{:<8}{:>4.2f}'.format('Mean:', np.mean(data)),
        '{:<8}{:>4.2f}'.format('SD:', np.std(data)),
])
plot_histo(data, stats)

plots like

Histogram

But, using a print statement:

print(stats)

outputs the desired, aligned, tabular format.

n:       100
Mean:   0.01
SD:     0.95

Any ideas on how to get the tabular formatting in a text box? Using a monospaced font is undesirable for the end application.

Upvotes: 1

Views: 1989

Answers (1)

Thomas909
Thomas909

Reputation: 147

The best I could come up with is to put the text in two separately aligned boxes with no background over an empty box with the background I want. Inelegant, but it works. Would be really annoying if you ever change the formatting.

def plot_histo(data):
    fig, ax = plt.subplots()
    n, bins, patches = plt.hist(data, bins=16, alpha=0.5)

    # empty text box with background color
    blanks = '\n'.join(['x'*10]*3)
    props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
    ax.text(0.8, 0.85, blanks, color='none', transform=ax.transAxes, bbox=props)

    # overlay statistics with titles left-aligned and numbers right-aligned
    stats_txt = '\n'.join(['n:', 'Mean:', 'SD:'])
    stats = '\n'.join([
        '{}'.format(len(data)),
        '{:0.2f}'.format(np.mean(data)),
        '{:0.2f}'.format(np.std(data))
    ])
    props = dict(boxstyle='square', facecolor='none', edgecolor='none')
    ax.text(0.8, 0.85, stats_txt, transform=ax.transAxes, bbox=props, ha='left')
    ax.text(0.96, 0.85, stats, transform=ax.transAxes, bbox=props, ha='right')
    plt.show()

Histo2

Upvotes: 4

Related Questions