3

I have created a figure that displays a shape and table using matplotlib. The problem is how its produced. They overlap each other. The shape is to scale so I don't want to alter it. I was wondering how I can alter the overall size of the plot or move the position of the table.

import matplotlib.pyplot as plt
import matplotlib as mpl

fig, ax = plt.subplots(figsize = (10,6))
ax.axis('equal')
plt.style.use('ggplot')
ax.grid(False)

xy = 0,0
circle = mpl.patches.Circle(xy, 160, lw = 3, edgecolor = 'black', color = 'b', alpha = 0.1, zorder = 5)
ax.add_patch(circle)   

col_labels=['A','B','C','D','E']
row_labels=['diff','total']

table_vals=[['','','','',''],['','','','','']]

the_table = plt.table(cellText=table_vals,
    colWidths = [0.05]*5,
    rowLabels=row_labels,
    colLabels=col_labels,
    bbox = [0.8, 0.4, 0.2, 0.2])

ax.autoscale()
plt.show()

enter image description here

3
  • Of course you can make the circle smaller, or modify xlim and ylim, or change the location of your table to a corner... possibilities are endless. Commented Jul 31, 2018 at 6:08
  • I've updated the question. The shape it to scale sorry so i can't change that. If I change the location of the table, it goes off the plot Commented Jul 31, 2018 at 6:39
  • What about top center instead of top right? Otherwise use bbox as suggested in the answers Commented Jul 31, 2018 at 8:38

2 Answers 2

6

Add the bbox argument with your table. (instead of loc)

the_table = plt.table(cellText=table_vals,
              colWidths = [0.05]*5,
              rowLabels=row_labels,
              colLabels=col_labels,
              bbox = [0.2, 0.4, 0.4, 0.02])

With BBOX

The bbox argument takes 4 inputs: X, Y, Width, Height. Thus X and Y are the coordinates of the bottom left corner. Above, the height was far too small.

EDIT: Create room to play with

The idea is to make the ax smaller in the same manner.

box = ax.get_position()
a.set_position([box.x0, box.y0, box.width * 0.9, box.height])

EDIT 2: Trying to put the table on the right. As I said, you need to play with the box values, took me about 10 tries to get this. I'm using spyder as an IDE, so it's really fast.

import matplotlib.pyplot as plt
import matplotlib as mpl

fig, ax = plt.subplots(figsize = (10,6))
ax.axis('equal')
plt.style.use('ggplot')
ax.grid(False)

xy = 0,0
circle = mpl.patches.Circle(xy, 160, lw = 3, edgecolor = 'black', color = 'b', alpha = 0.1, zorder = 5)
ax.add_patch(circle)   

col_labels=['A','B','C','D','E']
row_labels=['diff','total']

table_vals=[['','','','',''],['','','','','']]

the_table = plt.table(cellText=table_vals,
          colWidths = [0.05]*5,
          rowLabels=row_labels,
          colLabels=col_labels,
          bbox = [1.1, 0.5, 0.35, 0.1])

box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])

ax.autoscale()
plt.show()

Output:

Table on the right

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

7 Comments

Thanks @Mathieu. Is there anyway to extend the plot size as well. I can squeeze it in but it would be good to have more room to play with.
@Maxibon Yes, you can modify the position and size of the axis on the figure with the code in the EDIT. Let's say you want to place the plot on the left and the table on the right, the space on the side of your circle is useless, thus play with the width and the x position.
@Maxibon without more knowledge about what you want to do, I can't help more.
Thanks @Mathieu. Should that be ax.set_position([box.x0, box.y0, box.width * 0.9, box.height]) instead of a.set_position
@Maxibon Well you need to play with the values, with box.width * 0.9 you reduce the width by 10%. You might need more, you might need to shift the corner to another position (x0, y0), and so on...
|
3

Position the table outside the axes

You may use loc="right" to position the table right of the axes. Something like fig.subplots_adjust(right=0.8) will leave enough space for it.

import matplotlib.pyplot as plt
import matplotlib as mpl
plt.style.use('ggplot')

fig, ax = plt.subplots(figsize = (10,6))
fig.subplots_adjust(right=0.8)
ax.axis('equal')

ax.grid(False)

xy = 0,0
circle = mpl.patches.Circle(xy, 160, lw = 3, edgecolor = 'black', 
                            facecolor = 'b', alpha = 0.1, zorder = 5)
ax.add_patch(circle)   

col_labels=['A','B','C','D','E']
row_labels=['diff','total']

table_vals=[['','','','',''],['','','','','']]

the_table = plt.table(cellText=table_vals,
          colWidths = [0.05]*5,
          rowLabels=row_labels,
          colLabels=col_labels,
          loc='right', zorder=3)

ax.autoscale()
plt.show()

enter image description here

Put the table in its own axes

You may put the table in a new axes next to the existing one. The advantage is that there is no need to then play with the column width or subplot parameters.

import matplotlib.pyplot as plt
import matplotlib as mpl
plt.style.use('ggplot')

fig, (ax, ax_table) = plt.subplots(ncols=2, figsize = (10,6),
                                  gridspec_kw=dict(width_ratios=[3,1]))
ax.axis('equal')
ax_table.axis("off")

ax.grid(False)

xy = 0,0
circle = mpl.patches.Circle(xy, 160, lw = 3, edgecolor = 'black', 
                            facecolor = 'b', alpha = 0.1, zorder = 5)
ax.add_patch(circle)   

col_labels=['A','B','C','D','E']
row_labels=['diff','total']

table_vals=[['','','','',''],['','','','','']]

the_table = ax_table.table(cellText=table_vals,
          rowLabels=row_labels,
          colLabels=col_labels,
          loc='center')

ax.autoscale()
plt.show()

enter image description here

1 Comment

Thanks @ImportanceOfBeingErnest. This is good. Is it possible to have it on the same axis with the plot though. Please see question for more detail

Your Answer

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