0

I have table issues like this and obviously using the solution provided for that answer i can adjust the cells. What i don't understand is, without doing an eyeball test, how to detect that one is too big and the other is too small

Update The code creates the graph below. Note the size of text under the table and the size of text in the list. Under is too big, list is too small. How do i programmatically detect these conditions without having to visually look at the chart. enter image description here

import sys
import numpy as np
import pandas as pd
import random
import string
import matplotlib.pyplot as plt
import matplotlib.gridspec as grid_spec


def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
    return ''.join(random.choice(chars) for _ in range(size))

month_labels = "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
month_list = np.r_[1:13]
month_bar_width = .35


plt.ion()
with plt.style.context('fivethirtyeight'):
    fig = plt.figure(figsize=(8.5, 11))
    gs = grid_spec.GridSpec(3, 3)
    ax1 = plt.subplot(gs[0:2, 0:])
    ax2 = plt.subplot(gs[2:3, 0])

    names = [id_generator(10) for _ in range(20)]
    counts = [random.randint(0,50) for _ in range(12)]

    current_bbox = ax1.get_position()
    bottom_of_1 = current_bbox.y0
    current_bbox.y0 += (1 - current_bbox.y0) * .25
    ax1.set_position(current_bbox)

    cell_text = []
    row_labels = []
    row_colors = []
    bar_start = np.arange(len(month_list))
    bar_width = (bar_start[1] - bar_start[0]) * 0.7
    row_bottom = np.zeros(len(month_list))

    ax1.bar(bar_start, counts, width=bar_width)
    cell_text.append(counts)
    tbl = ax1.table(cellText=cell_text,loc='bottom')
    ax1.set_xticks([])

    rows = list(zip(names, counts))
    tbl = ax2.table(cellText=rows, loc='center')
    ax2.set_xticks([])
    ax2.set_yticks([])

Update 2 I can add the following code from the previous answer:

table_props = tbl.properties()
table_cells = table_props['child_artists']
for cell in table_cells: cell.set_height(0.1)

but the 0.1 is picked by eyeballing the graph and looking at the current value in height. What i'm looking for is how to calculate the 0.1 without looking at the graph. If the current height is .5 and the height is too small i need to make it larger, but if i want to make it smaller it has to be .4. What's the formula for knowing what situation you are in. Or conversely knowing the the height is ok but you need to change the font size.

Community
  • 1
  • 1
cryptoref
  • 413
  • 1
  • 7
  • 17
  • You question sounds unclear to me. Please provide a [minimal, complete and verifiable example](http://stackoverflow.com/help/mcve), and what you expect. – jrjc Mar 07 '16 at 11:26
  • Updated to illustrate the issue. – cryptoref Mar 07 '16 at 22:50
  • this is not a minimal, complete and verifiable example, although you made some effort. Please provide also what you expect and what you tried. – jrjc Mar 08 '16 at 14:13
  • Hopefully i've made it apparent what the question is. I'm trying to move from visual inspection to a programmatic method of adjusting the chart. I don't understand how to "know" what situation is present from inside the code without visually seeing the chart. – cryptoref Mar 08 '16 at 15:15
  • We should be a able to copy-past your code to make it work. So please include your imports, remove all unnecessary parts and functions. So far I can't. Just give us one piece of code, the smallest possible, which will produce the simplest figure. – jrjc Mar 08 '16 at 15:23
  • Added the imports, it works and creates the indicated graph in my environment (pycharm) – cryptoref Mar 08 '16 at 15:43

2 Answers2

0

In your update 2, you only change the second table.

Anyway I guess your looking for tight_layout() function, just try by adding this at the end:

plt.tight_layout(h_pad=2)

h_pad set the height space between two subplots, so here 2 is because you have a table with one row above. (Empirically determined though);

AFAIK, the only functions in matplotlib that can automatically change properties of the plot to adjust the spacing between elements is plt.tight_layout() and plt.savefig(..., bbox_inches="tight").

See here for more info: http://matplotlib.org/users/tight_layout_guide.html

HTH

jrjc
  • 21,103
  • 9
  • 64
  • 78
  • Thanks for looking, but tight_layout doesn't work. You have to eyeball to figure out how much pad to add and that's exactly what i'm trying to avoid. If you add a row in the table below it really changes the pad and then the sizes change and it's just not viable. My issue is that i don't know how many years of data someone will have. It could be 1 to 10, so i need to modify on the fly. – cryptoref Mar 10 '16 at 16:42
0

Don't try this at home, is the basic answer. If you only have one graph and table, then tight_layout will do the trick. If you have multiples of charts in one figure, nope it doesn't work.

My solution is to create a separate gridspec area just for the table entry. Put the table into the axis and then do tight_layout. This works. Table positioning can be tricky but i did get it to work.

cryptoref
  • 413
  • 1
  • 7
  • 17