Tables for matplotlib

Hi John, I've moved on a fair bit with this, still quite a

    > way to go.

Nice work. table_demo.py looks fairly wild -- prone to induce
seizures -- but table_demo2.py is nice.

    > axes.patch is a patch to axes.py that adds table support.

Could you provide context diffs, or just the whole file. I can diff
it myself or just copy and paste the relevant code.

    > Currently you have to specify the column widths for the
    > table. Really two cases should be supported: allow the user
    > to specify the widths (this is needed so you can line up
    > tables with bar plots) and allow the Table to auto-adjust
    > the widths to make everything just big enough for whatever
    > text is present (this is handy for legend type stuff). I've
    > done nothing for auto-guessing of widths as yet.

It can be a pain. I think you're taking the right approach - do the
easy case first. As you probably noticed, the legend does some
autolayout using bboxes and you can emulate this code if you want to
go this route.

    > I've made the grid within the tables an option + I think
    > with a little more work legend.py could just use table.py to
    > do what it has to do.

    > There is an ugly hack, rowOffset that I use in
    > table_demo2.py to get the row labels to align with the
    > appropriate data. My idea was that it might be simpler to
    > have a basic table object and then build up more complicated
    > stuff such as including row-labels by creating multiple
    > tables.

    > Currently I can't decide whether i wouldn't be better trying
    > to support the row/column labels all in the one object -- I
    > suspect this is the way to go since it is easier to get
    > things to line up this way rather than trying to align lots
    > of separate tables (eg if i start supporting different fonts
    > for different tables then we'll really be in trouble).

    > Now as I said there is still lots to do here.

    > There are all sorts of minor and not so minor alignment
    > issues to address -- a lot of these I think I can solve by
    > paying a bit more attention to the legend.py code.

    > The most significant problem at the moment is that the
    > tables are getting clipped -- I'm not sure how I control the
    > size of the border around the axes.

You need to manually set the axes. The figure size is fixed and the
axes take up a fixed proportion of the figure. In table_demo.py, put
the following at the top of your code

  axes([0.3, 0.3, 0.6, 0.6])

The default subplot(111) is much bigger than this and you can't fit
the whole axes and the table on the figure.

    > I'd also like to make it so you can specify that text should
    > be left/right/centre aligned.

    > There is also quite a bit of work to do on the actual
    > interface to the table objects, basically making them smart
    > about the parameters they are given so that simple cases
    > just work by magic. They are in danger of sprouting a
    > plethora of options + no-one will be able to figure out how
    > to use the things.

    > Anyway, so far it has been fun working with this stuff.

Last night I had a completely different idea that might be very nice.
Create a Cell object that subclasses patch.Rectangle but is
initialized with text. draw the text in the cell. You could easily
layout the text within the cell to be right, left, top, bottom,
justified using the text alignment properties. You would also have
full control of the face and edge color of the cells, so you could
have alternating colors for the rows, etc. Or you could make the
inner cells have a white face color and black edge color (standard
table look) or a white edge color. Ie, you would have total control.

You would build the table by placing a bunch of cells in rows and
columns.

One potential downside of this approach is that it might be hard to
see text over a dark color, and your current side-by-side approach
avoids this. But you could workaround this by having a colored cell
with no text next to a while cell with text, and so on. The other
downside is that it would mean more or less starting over. My guess
is that it would be a clean design and easy to implement.

If you go this route, I might advise you not to follow the legend
example and your current approach which is to pass line/patch
instances and use introspection to automagically determine the colors.
It would simplify your life if you just provided helper methods like

  set_row_facecolor(colorarg, i)
  set_row_edgecolor(colorarg, i)
  set_col_facecolor(colorarg, j)
  set_col_edgecolor(colorarg, j)
  set_cell_edgecolor(colorarg, i, j) and so on

Let the user build the table. We can supply a helper function to
automatically build tables from stacked bar charts using
introspection, but I think from a design standpoint you will make your
life a lot easier by separating out this functionality.

JDH

 *    John> Hi John, I've moved on a fair bit with this, still quite a
> way to go.
Nice work. table_demo.py looks fairly wild -- prone to induce
seizures -- but table_demo2.py is nice. *

I do a lot of this work on the train in and out of work – have to be careful running table_demo.py in case anyone is watching the screen.

 *
> axes.patch is a patch to axes.py that adds table support.
Could you provide context diffs, or just the whole file. I can diff
it myself or just copy and paste the relevant code.*

I’ve attached my version of axes.py.

Thanks for the axes tip – that is much better.

One other glitch that is showing up is when I resize the window (I’m using the GTK backend) for table_demo2.py the table with the row labels goes out of alignment with the other table – any ideas what is causing that?

I like the coloured patches with text idea – i’ll do some experiments and see how it looks. One thought I had is to turn the colours into light pastel shades so that dark text still stands out.

John

axes.py (43.1 KB)