28

I'm not having any success in getting the matplotlib table commands to work. Here's an example of what I'd like to do:

Can anyone help with the table construction code?

import pylab as plt

plt.figure()
ax=plt.gca()
y=[1,2,3,4,5,4,3,2,1,1,1,1,1,1,1,1]
plt.plot([10,10,14,14,10],[2,4,4,2,2],'r')
col_labels=['col1','col2','col3']
row_labels=['row1','row2','row3']
table_vals=[11,12,13,21,22,23,31,32,33]
# the rectangle is where I want to place the table
plt.text(11,4.1,'Table Title',size=8)
plt.plot(y)
plt.show()
2
  • 3
    Have you tried looking over this example? Or you might even be able to do something similar, but instead of the annotations, you have a table. Commented Dec 15, 2011 at 20:36
  • Yes I saw that example. When I tried to use the code I couldn't assign the row colors and placement. I also couldn't find any doc help on the syntax or type for the call. As for annotations, I believe there is more control specifying a second axes to plot the table in. Commented Dec 16, 2011 at 7:01

3 Answers 3

52

AFAIK, you can't arbitrarily place a table on the matplotlib plot using only native matplotlib features. What you can do is take advantage of the possibility of latex text rendering. However, in order to do this you should have working latex environment in your system. If you have one, you should be able to produce graphs such as below:

import pylab as plt
import matplotlib as mpl

mpl.rc('text', usetex=True)
plt.figure()
ax=plt.gca()
y=[1,2,3,4,5,4,3,2,1,1,1,1,1,1,1,1]
#plt.plot([10,10,14,14,10],[2,4,4,2,2],'r')
col_labels=['col1','col2','col3']
row_labels=['row1','row2','row3']
table_vals=[11,12,13,21,22,23,31,32,33]
table = r'''\begin{tabular}{ c | c | c | c } & col1 & col2 & col3 \\\hline row1 & 11 & 12 & 13 \\\hline row2 & 21 & 22 & 23 \\\hline  row3 & 31 & 32 & 33 \end{tabular}'''
plt.text(9,3.4,table,size=12)
plt.plot(y)
plt.show()

The result is:

enter image description here

Please take in mind that this is quick'n'dirty example; you should be able to place the table correctly by playing with text coordinates. Please also refer to the docs if you need to change fonts etc.

UPDATE: more on pyplot.table

According to the documentation, plt.table adds a table to current axes. From sources it's obvious, that table location on the graph is determined in relation to axes. Y coordinate can be controlled with keywords top (above graph), upper (in the upper half), center (in the center), lower (in the lower half) and bottom (below graph). X coordinate is controlled with keywords left and right. Any combination of the two works, e.g. any of top left, center right and bottom is OK to use.

So the closest graph to what you want could be made with:

import matplotlib.pylab as plt

plt.figure()
ax=plt.gca()
y=[1,2,3,4,5,4,3,2,1,1,1,1,1,1,1,1]
#plt.plot([10,10,14,14,10],[2,4,4,2,2],'r')
col_labels=['col1','col2','col3']
row_labels=['row1','row2','row3']
table_vals=[[11,12,13],[21,22,23],[31,32,33]]
# the rectangle is where I want to place the table
the_table = plt.table(cellText=table_vals,
                  colWidths = [0.1]*3,
                  rowLabels=row_labels,
                  colLabels=col_labels,
                  loc='center right')
plt.text(12,3.4,'Table Title',size=8)

plt.plot(y)
plt.show()

And this gives you

enter image description here

Hope this helps!

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

6 Comments

Thanks Andrey, This does provide a workable solution to the probelem. However I can't find any discussion/documentation of the pyplot.table or the matplotlib.Table.table capabilities in matplotlib. I'd like to see someone explicitly address the Table question.
If you want to see more on pyplot.table, please check the update.
Thank you Andrey! Not only did you answer the question clearly and completely but I completely missed the matplotlib.pyplot.table documentation. Thanks for the explicit answer and guidance.
Hi Andrey, I'd like to know if it is possible to drag the table out of the axes?
Thanks! All of the loc's available values cannot satisfy me, but I find a workaround: add a sub_plot and draw the table to that plot, then set the sub plot to invisible. since I can relocate the sub plot, that means I can locate the table anywhere.
|
11

I'm not sure if the previous answers satisfies your question, I was also looking for a way of adding a table to the plot and found the possibility to overcome the "loc" limitation. You can use bounding box to control the exact position of the table (this only contains the table creation but should be enough):

        tbl = ax1.table(
            cellText=[["a"], ["b"]],
            colWidths=[0.25, 0.25],
            rowLabels=[u"DATA", u"WERSJA"],
            loc="bottom", bbox=[0.25, -0.5, 0.5, 0.3])

        self.ui.main_plot.figure.subplots_adjust(bottom=0.4)

And the result is (I don't have the reputation to post images so here is a link): http://www.viresco.pl/media/test.png.

Note that the bbox units are normalized (not in plot scale).

1 Comment

The link is broken at the time of writing.
0

If you want to use subplots, you can create a table and then draw it into the second plot and align it that way. I find this solution cleaner as it removes the risk of cluttering up your graph. If doing this, the width_ratios property for subplots will allow you to resize the plot areas to make better use of the space.

You can do something along the lines of the following (width ratio is 90% and 10%) and get the graph at the bottom:

fig, (ax1,ax2) = plt.subplots(nrows=1,
                              ncols=2,
                              width_ratios=(0.9,0.1),
                              figsize=(12,8))

ax1.set_ylabel('Y-Axis')
ax1.set_xlabel('X-Axis')

ax1.hlines(UCL,xmin=-1,xmax=100,linestyles='dashed')
ax1.hlines(mean,xmin=-4,xmax=103,color='green')
ax1.hlines(LCL,xmin=-1,xmax=100,linestyles='dashed')
ax1.hlines(290,xmin=-1,xmax=100,color='red')
ax1.hlines(225,xmin=-1,xmax=100,color='red')

ax1.plot(dfSorted.[col1], dfSorted.[col2])
ax1.set_xticks([1, 31, 61, 91],'')
ax1.set_ylim(220, 295)
ax1.grid(True)

data = [[np.round(UCL,3)],
        [np.round(mean,3)],
        [np.round(sigma,3)],
        [np.round(LCL,3)],
        [290],
        [225]]
rows = ('UCL','Mean','Std. Dev.','LCL','USL', 'LSL')

ax2.set_axis_off()
data_table = ax2.table(cellText=data,
                       rowLabels=rows,
                       loc='upper center',
                       edges='open')

fig.suptitle('Control Chart')
plt.show()

Control chart with data table in separate subplot

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.