PyTabular Tutorial

Getting Started

First we will import the PyTabular package in addition to numpy for generating data.


In [1]:
import pytabular as pytab
import numpy as np

Next, we will create some data. The data will be a list of rows, which are themselves lists. We could also have made these an array or dataframe. Each element in the row will be a cell in the table.


In [2]:
header = [['', 'Treated', '', 'Control', ''],
          ['Measure', 'Male', 'Female', 'Male', 'Female']]
measures = ['var{}'.format(i) for i in xrange(10)]
data = np.random.randn(10,4).tolist()
data = [[measures[i]] + data[i] for i in xrange(10)]
data = header + data
for row in data:
    print(row)


['', 'Treated', '', 'Control', '']
['Measure', 'Male', 'Female', 'Male', 'Female']
['var0', -0.5167002846669395, 0.8792991702381884, -0.23458760961617128, -1.170934450548481]
['var1', 1.2766874170491465, -2.388787508406037, 0.14478016347766892, -0.698051209764256]
['var2', -0.917911618638518, -0.48691612442474386, 1.6154905671266235, 0.668942725639134]
['var3', -0.3980033341023787, 0.2572670032448797, -0.6501461980831177, -0.04094791588482208]
['var4', -0.04105450501464532, 0.7550309621974881, 1.880057958928697, -0.6309391852547932]
['var5', -2.042543228621894, -0.7847901021976253, -0.7161952485694157, 0.18595671706568329]
['var6', 1.230211159320553, 0.5667037845827531, 0.48070439857258684, -0.4797530876173052]
['var7', -0.5664050146523703, 1.738603705363104, 0.31496306003262386, -0.855603924247631]
['var8', 1.04475665654782, 0.5269310565689413, -0.3867085756799248, 1.6695958326249065]
['var9', -0.2393961663716263, -0.3602267115352322, 1.1220530606403945, -0.18108505711027828]

Creating a PyTabular object from this data is easy. From there, we can manipulate the table to customize the layout and look of the cells.


In [3]:
tabular = pytab.Tabular(data)
print('Shape:', tabular.shape)
print(tabular)


('Shape:', (12, 5))
\begin{ThreePartTable}
\begin{tabu}{ccccc}

   & Treated &  & Control &  \\  

  Measure & Male & Female & Male & Female \\  

  var0 & -0.516700284667 & 0.879299170238 & -0.234587609616 & -1.17093445055 \\  

  var1 & 1.27668741705 & -2.38878750841 & 0.144780163478 & -0.698051209764 \\  

  var2 & -0.917911618639 & -0.486916124425 & 1.61549056713 & 0.668942725639 \\  

  var3 & -0.398003334102 & 0.257267003245 & -0.650146198083 & -0.0409479158848 \\  

  var4 & -0.0410545050146 & 0.755030962197 & 1.88005795893 & -0.630939185255 \\  

  var5 & -2.04254322862 & -0.784790102198 & -0.716195248569 & 0.185956717066 \\  

  var6 & 1.23021115932 & 0.566703784583 & 0.480704398573 & -0.479753087617 \\  

  var7 & -0.566405014652 & 1.73860370536 & 0.314963060033 & -0.855603924248 \\  

  var8 & 1.04475665655 & 0.526931056569 & -0.38670857568 & 1.66959583262 \\  

  var9 & -0.239396166372 & -0.360226711535 & 1.12205306064 & -0.18108505711 \\  

\end{tabu}
\end{ThreePartTable}

Operating on the Table

Operate on the table using methods. Methods will either operate on the whole table or on the specific selection you make from the table. Make a selection using Python's slice syntax. Some examples include:

  • Select the cell in the upper-left:

    tabular[0,0]

  • Select the 2nd row:

    tabular[1]

  • Select the 1st column:

    tabular[:,0]

  • Select cells in the first row, the 2nd column to the last:

    tabular[:,1:]

  • Select cells in the 3rd column, from the 2nd to the 4th row:

    tabular[1:4,2]

Built-in methods either operate by-cell or to the table. Table methods, like set_tab_alignment operate on the whole table and should not be used on a selection. Other methods, like set_bold and merge operate on selections of the table. set_bold does the same thing to each cell in the selection. However, merge is a special function which we will explore next.

Merging Cells in the Header

  • Take a table, or a selection from a table and merge the selected cells together. The content for the merged block is taken from the cell in the upper-left. All operations on this merged cell should be applied to the cell in this upper-left location.

In [4]:
tabular[0,1:3].merge() #merges cells in row 0, columns 1 and 2
tabular[0,3:].merge() #merges cells in row 0, columns 3 and 4
print(tabular)


\begin{ThreePartTable}
\begin{tabu}{ccccc}

   & \mc{2}{c}{Treated} & \mc{2}{c}{Control} \\  

  Measure & Male & Female & Male & Female \\  

  var0 & -0.516700284667 & 0.879299170238 & -0.234587609616 & -1.17093445055 \\  

  var1 & 1.27668741705 & -2.38878750841 & 0.144780163478 & -0.698051209764 \\  

  var2 & -0.917911618639 & -0.486916124425 & 1.61549056713 & 0.668942725639 \\  

  var3 & -0.398003334102 & 0.257267003245 & -0.650146198083 & -0.0409479158848 \\  

  var4 & -0.0410545050146 & 0.755030962197 & 1.88005795893 & -0.630939185255 \\  

  var5 & -2.04254322862 & -0.784790102198 & -0.716195248569 & 0.185956717066 \\  

  var6 & 1.23021115932 & 0.566703784583 & 0.480704398573 & -0.479753087617 \\  

  var7 & -0.566405014652 & 1.73860370536 & 0.314963060033 & -0.855603924248 \\  

  var8 & 1.04475665655 & 0.526931056569 & -0.38670857568 & 1.66959583262 \\  

  var9 & -0.239396166372 & -0.360226711535 & 1.12205306064 & -0.18108505711 \\  

\end{tabu}
\end{ThreePartTable}

Now let's add some horizontal lines with set_lines option. set_lines(lines, narrow) takes two parameters:

  • lines: number of lines to place below

  • narrow: a string to tell cmidrule whether or not to shorten the line on either side of the cell, use 'r' to shorten on the right, 'l' for left and 'lr' on both

When using set_lines on merged cells, will produce a horizontal line extending across all of the cells merged together.


In [5]:
tabular[0,1:3].set_lines(lines=1, narrow='lr')
tabular[0,3:].set_lines(lines=2, narrow='lr')
print(tabular)


\begin{ThreePartTable}
\begin{tabu}{ccccc}

   & \mc{2}{c}{Treated} & \mc{2}{c}{Control} \\ 
  \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

  Measure & Male & Female & Male & Female \\  

  var0 & -0.516700284667 & 0.879299170238 & -0.234587609616 & -1.17093445055 \\  

  var1 & 1.27668741705 & -2.38878750841 & 0.144780163478 & -0.698051209764 \\  

  var2 & -0.917911618639 & -0.486916124425 & 1.61549056713 & 0.668942725639 \\  

  var3 & -0.398003334102 & 0.257267003245 & -0.650146198083 & -0.0409479158848 \\  

  var4 & -0.0410545050146 & 0.755030962197 & 1.88005795893 & -0.630939185255 \\  

  var5 & -2.04254322862 & -0.784790102198 & -0.716195248569 & 0.185956717066 \\  

  var6 & 1.23021115932 & 0.566703784583 & 0.480704398573 & -0.479753087617 \\  

  var7 & -0.566405014652 & 1.73860370536 & 0.314963060033 & -0.855603924248 \\  

  var8 & 1.04475665655 & 0.526931056569 & -0.38670857568 & 1.66959583262 \\  

  var9 & -0.239396166372 & -0.360226711535 & 1.12205306064 & -0.18108505711 \\  

\end{tabu}
\end{ThreePartTable}

And we will add a horizontal line below the 2nd row.


In [6]:
tabular[1].set_lines(2)
print(tabular)


\begin{ThreePartTable}
\begin{tabu}{ccccc}

   & \mc{2}{c}{Treated} & \mc{2}{c}{Control} \\ 
  \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

  Measure & Male & Female & Male & Female \\ 
  \hline \hline  

  var0 & -0.516700284667 & 0.879299170238 & -0.234587609616 & -1.17093445055 \\  

  var1 & 1.27668741705 & -2.38878750841 & 0.144780163478 & -0.698051209764 \\  

  var2 & -0.917911618639 & -0.486916124425 & 1.61549056713 & 0.668942725639 \\  

  var3 & -0.398003334102 & 0.257267003245 & -0.650146198083 & -0.0409479158848 \\  

  var4 & -0.0410545050146 & 0.755030962197 & 1.88005795893 & -0.630939185255 \\  

  var5 & -2.04254322862 & -0.784790102198 & -0.716195248569 & 0.185956717066 \\  

  var6 & 1.23021115932 & 0.566703784583 & 0.480704398573 & -0.479753087617 \\  

  var7 & -0.566405014652 & 1.73860370536 & 0.314963060033 & -0.855603924248 \\  

  var8 & 1.04475665655 & 0.526931056569 & -0.38670857568 & 1.66959583262 \\  

  var9 & -0.239396166372 & -0.360226711535 & 1.12205306064 & -0.18108505711 \\  

\end{tabu}
\end{ThreePartTable}

Custom Formatters

As-is, the data in the cells is shown with too many significant digits and it is overwhelming. While we allow the user to pass in any formatter (a function which takes a cell value and returns a formatted value as a string), we provide some built-in formatters:

  • set_digits sets the number of significant digits displayed in cells

In [7]:
tabular[2:,1:].set_digits(3)
print(tabular)


\begin{ThreePartTable}
\begin{tabu}{ccccc}

   & \mc{2}{c}{Treated} & \mc{2}{c}{Control} \\ 
  \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

  Measure & Male & Female & Male & Female \\ 
  \hline \hline  

  var0 & -0.517 & 0.879 & -0.235 & -1.171 \\  

  var1 & 1.277 & -2.389 & 0.145 & -0.698 \\  

  var2 & -0.918 & -0.487 & 1.615 & 0.669 \\  

  var3 & -0.398 & 0.257 & -0.650 & -0.041 \\  

  var4 & -0.041 & 0.755 & 1.880 & -0.631 \\  

  var5 & -2.043 & -0.785 & -0.716 & 0.186 \\  

  var6 & 1.230 & 0.567 & 0.481 & -0.480 \\  

  var7 & -0.566 & 1.739 & 0.315 & -0.856 \\  

  var8 & 1.045 & 0.527 & -0.387 & 1.670 \\  

  var9 & -0.239 & -0.360 & 1.122 & -0.181 \\  

\end{tabu}
\end{ThreePartTable}

Adding Data

What if we have data from another table that we want to include? Let's say we forgot to include an observations column.


In [8]:
# obs = a column of data we forgot about
obs = np.array(['', 'Observations'] + np.random.randint(500, 100000, 10).tolist()).reshape((-1,1))
add = pytab.Tabular(obs)
print(add.shape)
print(tabular.shape)


(12, 1)
(12, 5)

We will use hstack to stack additional columns to the right of our previous table. NOTE: Use vstack to tack on an additional row.


In [9]:
newtabular = pytab.hstack(tabular, add)
print(newtabular)


\begin{ThreePartTable}
\begin{tabu}{cccccc}

   & Treated &  & Control &  &  \\  

  Measure & Male & Female & Male & Female & Observations \\  

  var0 & -0.516700284667 & 0.879299170238 & -0.234587609616 & -1.17093445055 & 28310 \\  

  var1 & 1.27668741705 & -2.38878750841 & 0.144780163478 & -0.698051209764 & 81208 \\  

  var2 & -0.917911618639 & -0.486916124425 & 1.61549056713 & 0.668942725639 & 63223 \\  

  var3 & -0.398003334102 & 0.257267003245 & -0.650146198083 & -0.0409479158848 & 22335 \\  

  var4 & -0.0410545050146 & 0.755030962197 & 1.88005795893 & -0.630939185255 & 41208 \\  

  var5 & -2.04254322862 & -0.784790102198 & -0.716195248569 & 0.185956717066 & 24782 \\  

  var6 & 1.23021115932 & 0.566703784583 & 0.480704398573 & -0.479753087617 & 43490 \\  

  var7 & -0.566405014652 & 1.73860370536 & 0.314963060033 & -0.855603924248 & 39933 \\  

  var8 & 1.04475665655 & 0.526931056569 & -0.38670857568 & 1.66959583262 & 63132 \\  

  var9 & -0.239396166372 & -0.360226711535 & 1.12205306064 & -0.18108505711 & 56453 \\  

\end{tabu}
\end{ThreePartTable}

Notice that all of the formatting we have just done has gone away. The cells have reverted to their default values so as to not cause any conflicts with data in the cells. Its a good idea then to add tables before you do formatting. We can repeat all of the previous steps.


In [10]:
newtabular[0,1:3].merge() #merges cells in row 0, columns 1 and 2
newtabular[0,3:-1].merge() #merges cells in row 0, columns 3 and 4
newtabular[0,1:3].set_lines(lines=1, narrow='lr')
newtabular[0,3:-1].set_lines(lines=2, narrow='lr')
newtabular[1].set_lines(2)
newtabular[2:,1:-1].set_digits(3)
print(newtabular)


\begin{ThreePartTable}
\begin{tabu}{cccccc}

   & \mc{2}{c}{Treated} & \mc{2}{c}{Control} &  \\ 
  \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

  Measure & Male & Female & Male & Female & Observations \\ 
  \hline \hline  

  var0 & -0.517 & 0.879 & -0.235 & -1.171 & 28310 \\  

  var1 & 1.277 & -2.389 & 0.145 & -0.698 & 81208 \\  

  var2 & -0.918 & -0.487 & 1.615 & 0.669 & 63223 \\  

  var3 & -0.398 & 0.257 & -0.650 & -0.041 & 22335 \\  

  var4 & -0.041 & 0.755 & 1.880 & -0.631 & 41208 \\  

  var5 & -2.043 & -0.785 & -0.716 & 0.186 & 24782 \\  

  var6 & 1.230 & 0.567 & 0.481 & -0.480 & 43490 \\  

  var7 & -0.566 & 1.739 & 0.315 & -0.856 & 39933 \\  

  var8 & 1.045 & 0.527 & -0.387 & 1.670 & 63132 \\  

  var9 & -0.239 & -0.360 & 1.122 & -0.181 & 56453 \\  

\end{tabu}
\end{ThreePartTable}

But notice that the right-most column contains very large integers. Included in PyTabular is a formatter for integers. Let's try it out! Remember you can define your own custom formatters use the set_formatter as well.


In [11]:
newtabular[2:,-1].set_formatter(pytab.format_int)
print(newtabular)


\begin{ThreePartTable}
\begin{tabu}{cccccc}

   & \mc{2}{c}{Treated} & \mc{2}{c}{Control} &  \\ 
  \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

  Measure & Male & Female & Male & Female & Observations \\ 
  \hline \hline  

  var0 & -0.517 & 0.879 & -0.235 & -1.171 & 28,310 \\  

  var1 & 1.277 & -2.389 & 0.145 & -0.698 & 81,208 \\  

  var2 & -0.918 & -0.487 & 1.615 & 0.669 & 63,223 \\  

  var3 & -0.398 & 0.257 & -0.650 & -0.041 & 22,335 \\  

  var4 & -0.041 & 0.755 & 1.880 & -0.631 & 41,208 \\  

  var5 & -2.043 & -0.785 & -0.716 & 0.186 & 24,782 \\  

  var6 & 1.230 & 0.567 & 0.481 & -0.480 & 43,490 \\  

  var7 & -0.566 & 1.739 & 0.315 & -0.856 & 39,933 \\  

  var8 & 1.045 & 0.527 & -0.387 & 1.670 & 63,132 \\  

  var9 & -0.239 & -0.360 & 1.122 & -0.181 & 56,453 \\  

\end{tabu}
\end{ThreePartTable}

Exploring the Options

PyTabular contains many methods for customizing the look of your tables. Using a method on a table selection will apply that method to all of the cells in the selection.

  • bold cells with set_bold
  • emphasize (italicize) cells with set_emph
  • set the fontsize of cells with set_fontsize
  • set the color of cells with set_color

In [12]:
newtabular[0].set_bold()  #bolds all cells in first row
newtabular[1].set_emph() #italicizes cell in 2nd row
newtabular[0].set_fontsize('Large') #Huge fontsize for cells in first row
newtabular[2:,1:].set_alignment('r') #right align the cells containing numbers
newtabular[2:,0].set_alignment('l|') #left align and add vertical line to right
newtabular[5].set_color(color='gray',opacity=40) #highlight the cells in the 6th row 
newtabular[1].set_rotation(45) #rotate the content in row 2 45 degrees
newtabular[1].set_space_below('0.3cm') #puts space below the 2nd row
newtabular[2].set_space_above('0.3cm') #puts space above the 3nd row
print(newtabular)


\begin{ThreePartTable}
\begin{tabu}{cccccc}

   & \mc{2}{c}{\textbf{\Large{Treated}}} & \mc{2}{c}{\textbf{\Large{Control}}} &  \\ 
  \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

  \rotatebox{45}{\emph{Measure}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Observations}} \\[0.3cm] 
  \hline \hline  

  \\[0.3cm]
  \mc{1}{l|}{var0} & \mc{1}{r}{-0.517} & \mc{1}{r}{0.879} & \mc{1}{r}{-0.235} & \mc{1}{r}{-1.171} & \mc{1}{r}{28,310} \\  

  \mc{1}{l|}{var1} & \mc{1}{r}{1.277} & \mc{1}{r}{-2.389} & \mc{1}{r}{0.145} & \mc{1}{r}{-0.698} & \mc{1}{r}{81,208} \\  

  \mc{1}{l|}{var2} & \mc{1}{r}{-0.918} & \mc{1}{r}{-0.487} & \mc{1}{r}{1.615} & \mc{1}{r}{0.669} & \mc{1}{r}{63,223} \\  

  \mc{1}{l|}{\cellcolor{gray!40}{var3}} & \mc{1}{r}{\cellcolor{gray!40}{-0.398}} & \mc{1}{r}{\cellcolor{gray!40}{0.257}} & \mc{1}{r}{\cellcolor{gray!40}{-0.650}} & \mc{1}{r}{\cellcolor{gray!40}{-0.041}} & \mc{1}{r}{\cellcolor{gray!40}{22,335}} \\  

  \mc{1}{l|}{var4} & \mc{1}{r}{-0.041} & \mc{1}{r}{0.755} & \mc{1}{r}{1.880} & \mc{1}{r}{-0.631} & \mc{1}{r}{41,208} \\  

  \mc{1}{l|}{var5} & \mc{1}{r}{-2.043} & \mc{1}{r}{-0.785} & \mc{1}{r}{-0.716} & \mc{1}{r}{0.186} & \mc{1}{r}{24,782} \\  

  \mc{1}{l|}{var6} & \mc{1}{r}{1.230} & \mc{1}{r}{0.567} & \mc{1}{r}{0.481} & \mc{1}{r}{-0.480} & \mc{1}{r}{43,490} \\  

  \mc{1}{l|}{var7} & \mc{1}{r}{-0.566} & \mc{1}{r}{1.739} & \mc{1}{r}{0.315} & \mc{1}{r}{-0.856} & \mc{1}{r}{39,933} \\  

  \mc{1}{l|}{var8} & \mc{1}{r}{1.045} & \mc{1}{r}{0.527} & \mc{1}{r}{-0.387} & \mc{1}{r}{1.670} & \mc{1}{r}{63,132} \\  

  \mc{1}{l|}{var9} & \mc{1}{r}{-0.239} & \mc{1}{r}{-0.360} & \mc{1}{r}{1.122} & \mc{1}{r}{-0.181} & \mc{1}{r}{56,453} \\  

\end{tabu}
\end{ThreePartTable}

Spacing between Columns

  • use the set_tab_alignment method

In [13]:
# Set the spacing between columns by specifying a custom tabular string
# i.e. the string "cccccc" in "\being{tabular}{cccccc}"
newtabular.set_tab_alignment('cp{2cm}p{2cm}p{2cm}p{2cm}p{2cm}')
print(newtabular)


\begin{ThreePartTable}
\begin{tabu}{cp{2cm}p{2cm}p{2cm}p{2cm}p{2cm}}

   & \mc{2}{c}{\textbf{\Large{Treated}}} & \mc{2}{c}{\textbf{\Large{Control}}} &  \\ 
  \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

  \rotatebox{45}{\emph{Measure}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Observations}} \\[0.3cm] 
  \hline \hline  

  \\[0.3cm]
  \mc{1}{l|}{var0} & \mc{1}{r}{-0.517} & \mc{1}{r}{0.879} & \mc{1}{r}{-0.235} & \mc{1}{r}{-1.171} & \mc{1}{r}{28,310} \\  

  \mc{1}{l|}{var1} & \mc{1}{r}{1.277} & \mc{1}{r}{-2.389} & \mc{1}{r}{0.145} & \mc{1}{r}{-0.698} & \mc{1}{r}{81,208} \\  

  \mc{1}{l|}{var2} & \mc{1}{r}{-0.918} & \mc{1}{r}{-0.487} & \mc{1}{r}{1.615} & \mc{1}{r}{0.669} & \mc{1}{r}{63,223} \\  

  \mc{1}{l|}{\cellcolor{gray!40}{var3}} & \mc{1}{r}{\cellcolor{gray!40}{-0.398}} & \mc{1}{r}{\cellcolor{gray!40}{0.257}} & \mc{1}{r}{\cellcolor{gray!40}{-0.650}} & \mc{1}{r}{\cellcolor{gray!40}{-0.041}} & \mc{1}{r}{\cellcolor{gray!40}{22,335}} \\  

  \mc{1}{l|}{var4} & \mc{1}{r}{-0.041} & \mc{1}{r}{0.755} & \mc{1}{r}{1.880} & \mc{1}{r}{-0.631} & \mc{1}{r}{41,208} \\  

  \mc{1}{l|}{var5} & \mc{1}{r}{-2.043} & \mc{1}{r}{-0.785} & \mc{1}{r}{-0.716} & \mc{1}{r}{0.186} & \mc{1}{r}{24,782} \\  

  \mc{1}{l|}{var6} & \mc{1}{r}{1.230} & \mc{1}{r}{0.567} & \mc{1}{r}{0.481} & \mc{1}{r}{-0.480} & \mc{1}{r}{43,490} \\  

  \mc{1}{l|}{var7} & \mc{1}{r}{-0.566} & \mc{1}{r}{1.739} & \mc{1}{r}{0.315} & \mc{1}{r}{-0.856} & \mc{1}{r}{39,933} \\  

  \mc{1}{l|}{var8} & \mc{1}{r}{1.045} & \mc{1}{r}{0.527} & \mc{1}{r}{-0.387} & \mc{1}{r}{1.670} & \mc{1}{r}{63,132} \\  

  \mc{1}{l|}{var9} & \mc{1}{r}{-0.239} & \mc{1}{r}{-0.360} & \mc{1}{r}{1.122} & \mc{1}{r}{-0.181} & \mc{1}{r}{56,453} \\  

\end{tabu}
\end{ThreePartTable}

Casting as Other Types of Tables

Casting as other table types will nest the tabular environment inside a table environment, or, in the case of Longtables, change from the tabu environment to the longtabu environment.

In both cases, additional table methods become available. These include set_caption, set_label, and set_location.

Table Environments:

  • Table (LateX table environment)
  • LongTable (LateX longtabu environment)

    The LongTable class allows the table to overflow on multiple pages. It has an method set_repeats where the user can specify which rows to repeat on every page.


In [14]:
table = pytab.Table(newtabular)

In [15]:
print(table)


\begin{table}\centering
\captionsetup{singlelinecheck=false,justification=centering}
\caption{Table 1 \label{table1}}

  \begin{ThreePartTable}
  \begin{tabu}{cccccc}

     & \mc{2}{c}{\textbf{\Large{Treated}}} & \mc{2}{c}{\textbf{\Large{Control}}} &  \\ 
    \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

    \rotatebox{45}{\emph{Measure}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Observations}} \\[0.3cm] 
    \hline \hline  

    \\[0.3cm]
    \mc{1}{l|}{var0} & \mc{1}{r}{-0.517} & \mc{1}{r}{0.879} & \mc{1}{r}{-0.235} & \mc{1}{r}{-1.171} & \mc{1}{r}{28,310} \\  

    \mc{1}{l|}{var1} & \mc{1}{r}{1.277} & \mc{1}{r}{-2.389} & \mc{1}{r}{0.145} & \mc{1}{r}{-0.698} & \mc{1}{r}{81,208} \\  

    \mc{1}{l|}{var2} & \mc{1}{r}{-0.918} & \mc{1}{r}{-0.487} & \mc{1}{r}{1.615} & \mc{1}{r}{0.669} & \mc{1}{r}{63,223} \\  

    \mc{1}{l|}{\cellcolor{gray!40}{var3}} & \mc{1}{r}{\cellcolor{gray!40}{-0.398}} & \mc{1}{r}{\cellcolor{gray!40}{0.257}} & \mc{1}{r}{\cellcolor{gray!40}{-0.650}} & \mc{1}{r}{\cellcolor{gray!40}{-0.041}} & \mc{1}{r}{\cellcolor{gray!40}{22,335}} \\  

    \mc{1}{l|}{var4} & \mc{1}{r}{-0.041} & \mc{1}{r}{0.755} & \mc{1}{r}{1.880} & \mc{1}{r}{-0.631} & \mc{1}{r}{41,208} \\  

    \mc{1}{l|}{var5} & \mc{1}{r}{-2.043} & \mc{1}{r}{-0.785} & \mc{1}{r}{-0.716} & \mc{1}{r}{0.186} & \mc{1}{r}{24,782} \\  

    \mc{1}{l|}{var6} & \mc{1}{r}{1.230} & \mc{1}{r}{0.567} & \mc{1}{r}{0.481} & \mc{1}{r}{-0.480} & \mc{1}{r}{43,490} \\  

    \mc{1}{l|}{var7} & \mc{1}{r}{-0.566} & \mc{1}{r}{1.739} & \mc{1}{r}{0.315} & \mc{1}{r}{-0.856} & \mc{1}{r}{39,933} \\  

    \mc{1}{l|}{var8} & \mc{1}{r}{1.045} & \mc{1}{r}{0.527} & \mc{1}{r}{-0.387} & \mc{1}{r}{1.670} & \mc{1}{r}{63,132} \\  

    \mc{1}{l|}{var9} & \mc{1}{r}{-0.239} & \mc{1}{r}{-0.360} & \mc{1}{r}{1.122} & \mc{1}{r}{-0.181} & \mc{1}{r}{56,453} \\  

  \end{tabu}
  \end{ThreePartTable}

\end{table}

In [16]:
longtable = pytab.LongTable(newtabular)
print(longtable)


\begin{ThreePartTable}
\begin{longtabu}{cccccc}

  \centering \\
  \captionsetup{singlelinecheck=false,justification=centering}
  \caption{Table 1 \label{table1}} \\
   & \mc{2}{c}{\textbf{\Large{Treated}}} & \mc{2}{c}{\textbf{\Large{Control}}} &  \\ 
  \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

  \endfirsthead

  \mc{6}{c}{\tablename\ \thetable\ -- \emph{Continued from previous page}} \\
   & \mc{2}{c}{\textbf{\Large{Treated}}} & \mc{2}{c}{\textbf{\Large{Control}}} &  \\ 
  \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

  \endhead

  \mc{6}{r}{\emph{Continued on next page}} \\

  \endfoot
  \endlastfoot

  \rotatebox{45}{\emph{Measure}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Observations}} \\[0.3cm] 
  \hline \hline  

  \\[0.3cm]
  \mc{1}{l|}{var0} & \mc{1}{r}{-0.517} & \mc{1}{r}{0.879} & \mc{1}{r}{-0.235} & \mc{1}{r}{-1.171} & \mc{1}{r}{28,310} \\  

  \mc{1}{l|}{var1} & \mc{1}{r}{1.277} & \mc{1}{r}{-2.389} & \mc{1}{r}{0.145} & \mc{1}{r}{-0.698} & \mc{1}{r}{81,208} \\  

  \mc{1}{l|}{var2} & \mc{1}{r}{-0.918} & \mc{1}{r}{-0.487} & \mc{1}{r}{1.615} & \mc{1}{r}{0.669} & \mc{1}{r}{63,223} \\  

  \mc{1}{l|}{\cellcolor{gray!40}{var3}} & \mc{1}{r}{\cellcolor{gray!40}{-0.398}} & \mc{1}{r}{\cellcolor{gray!40}{0.257}} & \mc{1}{r}{\cellcolor{gray!40}{-0.650}} & \mc{1}{r}{\cellcolor{gray!40}{-0.041}} & \mc{1}{r}{\cellcolor{gray!40}{22,335}} \\  

  \mc{1}{l|}{var4} & \mc{1}{r}{-0.041} & \mc{1}{r}{0.755} & \mc{1}{r}{1.880} & \mc{1}{r}{-0.631} & \mc{1}{r}{41,208} \\  

  \mc{1}{l|}{var5} & \mc{1}{r}{-2.043} & \mc{1}{r}{-0.785} & \mc{1}{r}{-0.716} & \mc{1}{r}{0.186} & \mc{1}{r}{24,782} \\  

  \mc{1}{l|}{var6} & \mc{1}{r}{1.230} & \mc{1}{r}{0.567} & \mc{1}{r}{0.481} & \mc{1}{r}{-0.480} & \mc{1}{r}{43,490} \\  

  \mc{1}{l|}{var7} & \mc{1}{r}{-0.566} & \mc{1}{r}{1.739} & \mc{1}{r}{0.315} & \mc{1}{r}{-0.856} & \mc{1}{r}{39,933} \\  

  \mc{1}{l|}{var8} & \mc{1}{r}{1.045} & \mc{1}{r}{0.527} & \mc{1}{r}{-0.387} & \mc{1}{r}{1.670} & \mc{1}{r}{63,132} \\  

  \mc{1}{l|}{var9} & \mc{1}{r}{-0.239} & \mc{1}{r}{-0.360} & \mc{1}{r}{1.122} & \mc{1}{r}{-0.181} & \mc{1}{r}{56,453} \\  

\end{longtabu}
\end{ThreePartTable}

Table Methods

  • set_caption: give table a caption
  • set_label: give table a label
  • set_location: justify the table center='c', left='l' or right='r'
  • add_note: add a footnote to the table

LongTable Only:

  • set_repeats: tell LateX how many rows to repeat at the top of each page; this usually is the number of header rows in your table

In [17]:
table.set_caption('A Table with Numbers')
table.set_label('tab:table1')
table.set_location('l')
table.add_note('This is a footnote')
table.add_note('This is another footnote')
table.add_note('[1]This footnote has a superscript')
print(table)


\begin{table}\raggedright
\captionsetup{singlelinecheck=false,justification=raggedright}
\caption{A Table with Numbers \label{tab:table1}}

  \begin{ThreePartTable}
  \begin{tabu}{cccccc}

     & \mc{2}{c}{\textbf{\Large{Treated}}} & \mc{2}{c}{\textbf{\Large{Control}}} &  \\ 
    \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

    \rotatebox{45}{\emph{Measure}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Observations}} \\[0.3cm] 
    \hline \hline  

    \\[0.3cm]
    \mc{1}{l|}{var0} & \mc{1}{r}{-0.517} & \mc{1}{r}{0.879} & \mc{1}{r}{-0.235} & \mc{1}{r}{-1.171} & \mc{1}{r}{28,310} \\  

    \mc{1}{l|}{var1} & \mc{1}{r}{1.277} & \mc{1}{r}{-2.389} & \mc{1}{r}{0.145} & \mc{1}{r}{-0.698} & \mc{1}{r}{81,208} \\  

    \mc{1}{l|}{var2} & \mc{1}{r}{-0.918} & \mc{1}{r}{-0.487} & \mc{1}{r}{1.615} & \mc{1}{r}{0.669} & \mc{1}{r}{63,223} \\  

    \mc{1}{l|}{\cellcolor{gray!40}{var3}} & \mc{1}{r}{\cellcolor{gray!40}{-0.398}} & \mc{1}{r}{\cellcolor{gray!40}{0.257}} & \mc{1}{r}{\cellcolor{gray!40}{-0.650}} & \mc{1}{r}{\cellcolor{gray!40}{-0.041}} & \mc{1}{r}{\cellcolor{gray!40}{22,335}} \\  

    \mc{1}{l|}{var4} & \mc{1}{r}{-0.041} & \mc{1}{r}{0.755} & \mc{1}{r}{1.880} & \mc{1}{r}{-0.631} & \mc{1}{r}{41,208} \\  

    \mc{1}{l|}{var5} & \mc{1}{r}{-2.043} & \mc{1}{r}{-0.785} & \mc{1}{r}{-0.716} & \mc{1}{r}{0.186} & \mc{1}{r}{24,782} \\  

    \mc{1}{l|}{var6} & \mc{1}{r}{1.230} & \mc{1}{r}{0.567} & \mc{1}{r}{0.481} & \mc{1}{r}{-0.480} & \mc{1}{r}{43,490} \\  

    \mc{1}{l|}{var7} & \mc{1}{r}{-0.566} & \mc{1}{r}{1.739} & \mc{1}{r}{0.315} & \mc{1}{r}{-0.856} & \mc{1}{r}{39,933} \\  

    \mc{1}{l|}{var8} & \mc{1}{r}{1.045} & \mc{1}{r}{0.527} & \mc{1}{r}{-0.387} & \mc{1}{r}{1.670} & \mc{1}{r}{63,132} \\  

    \mc{1}{l|}{var9} & \mc{1}{r}{-0.239} & \mc{1}{r}{-0.360} & \mc{1}{r}{1.122} & \mc{1}{r}{-0.181} & \mc{1}{r}{56,453} \\  

  \end{tabu}
    \begin{tablenotes}
    \scriptsize
    \item This is a footnote
    \item This is another footnote
    \item [1]This footnote has a superscript
    \end{tablenotes}
  \end{ThreePartTable}

\end{table}

In [18]:
longtable.set_repeats(2)
longtable.add_note('Footnote for a long table.')
print(longtable)


\begin{ThreePartTable}
\begin{longtabu}{cccccc}

  \centering \\
  \captionsetup{singlelinecheck=false,justification=centering}
  \caption{Table 1 \label{table1}} \\
   & \mc{2}{c}{\textbf{\Large{Treated}}} & \mc{2}{c}{\textbf{\Large{Control}}} &  \\ 
  \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

  \rotatebox{45}{\emph{Measure}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Observations}} \\[0.3cm] 
  \hline \hline  

  \endfirsthead

  \mc{6}{c}{\tablename\ \thetable\ -- \emph{Continued from previous page}} \\
   & \mc{2}{c}{\textbf{\Large{Treated}}} & \mc{2}{c}{\textbf{\Large{Control}}} &  \\ 
  \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

  \rotatebox{45}{\emph{Measure}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Observations}} \\[0.3cm] 
  \hline \hline  

  \endhead

  \mc{6}{r}{\emph{Continued on next page}} \\

  \endfoot
  \endlastfoot

  \\[0.3cm]
  \mc{1}{l|}{var0} & \mc{1}{r}{-0.517} & \mc{1}{r}{0.879} & \mc{1}{r}{-0.235} & \mc{1}{r}{-1.171} & \mc{1}{r}{28,310} \\  

  \mc{1}{l|}{var1} & \mc{1}{r}{1.277} & \mc{1}{r}{-2.389} & \mc{1}{r}{0.145} & \mc{1}{r}{-0.698} & \mc{1}{r}{81,208} \\  

  \mc{1}{l|}{var2} & \mc{1}{r}{-0.918} & \mc{1}{r}{-0.487} & \mc{1}{r}{1.615} & \mc{1}{r}{0.669} & \mc{1}{r}{63,223} \\  

  \mc{1}{l|}{\cellcolor{gray!40}{var3}} & \mc{1}{r}{\cellcolor{gray!40}{-0.398}} & \mc{1}{r}{\cellcolor{gray!40}{0.257}} & \mc{1}{r}{\cellcolor{gray!40}{-0.650}} & \mc{1}{r}{\cellcolor{gray!40}{-0.041}} & \mc{1}{r}{\cellcolor{gray!40}{22,335}} \\  

  \mc{1}{l|}{var4} & \mc{1}{r}{-0.041} & \mc{1}{r}{0.755} & \mc{1}{r}{1.880} & \mc{1}{r}{-0.631} & \mc{1}{r}{41,208} \\  

  \mc{1}{l|}{var5} & \mc{1}{r}{-2.043} & \mc{1}{r}{-0.785} & \mc{1}{r}{-0.716} & \mc{1}{r}{0.186} & \mc{1}{r}{24,782} \\  

  \mc{1}{l|}{var6} & \mc{1}{r}{1.230} & \mc{1}{r}{0.567} & \mc{1}{r}{0.481} & \mc{1}{r}{-0.480} & \mc{1}{r}{43,490} \\  

  \mc{1}{l|}{var7} & \mc{1}{r}{-0.566} & \mc{1}{r}{1.739} & \mc{1}{r}{0.315} & \mc{1}{r}{-0.856} & \mc{1}{r}{39,933} \\  

  \mc{1}{l|}{var8} & \mc{1}{r}{1.045} & \mc{1}{r}{0.527} & \mc{1}{r}{-0.387} & \mc{1}{r}{1.670} & \mc{1}{r}{63,132} \\  

  \mc{1}{l|}{var9} & \mc{1}{r}{-0.239} & \mc{1}{r}{-0.360} & \mc{1}{r}{1.122} & \mc{1}{r}{-0.181} & \mc{1}{r}{56,453} \\  

\end{longtabu}
  \begin{tablenotes}
  \scriptsize
  \item Footnote for a long table.
  \end{tablenotes}
\end{ThreePartTable}

Nesting Inside Other Environments

You can have PyTabular next tables inside other environments. For instance, the landscape environment.

  • add_environment

In [19]:
longtable.add_environment('landscape')
print(longtable)


\begin{landscape}

  \begin{ThreePartTable}
  \begin{longtabu}{cccccc}

    \centering \\
    \captionsetup{singlelinecheck=false,justification=centering}
    \caption{Table 1 \label{table1}} \\
     & \mc{2}{c}{\textbf{\Large{Treated}}} & \mc{2}{c}{\textbf{\Large{Control}}} &  \\ 
    \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

    \rotatebox{45}{\emph{Measure}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Observations}} \\[0.3cm] 
    \hline \hline  

    \endfirsthead

    \mc{6}{c}{\tablename\ \thetable\ -- \emph{Continued from previous page}} \\
     & \mc{2}{c}{\textbf{\Large{Treated}}} & \mc{2}{c}{\textbf{\Large{Control}}} &  \\ 
    \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

    \rotatebox{45}{\emph{Measure}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Observations}} \\[0.3cm] 
    \hline \hline  

    \endhead

    \mc{6}{r}{\emph{Continued on next page}} \\

    \endfoot
    \endlastfoot

    \\[0.3cm]
    \mc{1}{l|}{var0} & \mc{1}{r}{-0.517} & \mc{1}{r}{0.879} & \mc{1}{r}{-0.235} & \mc{1}{r}{-1.171} & \mc{1}{r}{28,310} \\  

    \mc{1}{l|}{var1} & \mc{1}{r}{1.277} & \mc{1}{r}{-2.389} & \mc{1}{r}{0.145} & \mc{1}{r}{-0.698} & \mc{1}{r}{81,208} \\  

    \mc{1}{l|}{var2} & \mc{1}{r}{-0.918} & \mc{1}{r}{-0.487} & \mc{1}{r}{1.615} & \mc{1}{r}{0.669} & \mc{1}{r}{63,223} \\  

    \mc{1}{l|}{\cellcolor{gray!40}{var3}} & \mc{1}{r}{\cellcolor{gray!40}{-0.398}} & \mc{1}{r}{\cellcolor{gray!40}{0.257}} & \mc{1}{r}{\cellcolor{gray!40}{-0.650}} & \mc{1}{r}{\cellcolor{gray!40}{-0.041}} & \mc{1}{r}{\cellcolor{gray!40}{22,335}} \\  

    \mc{1}{l|}{var4} & \mc{1}{r}{-0.041} & \mc{1}{r}{0.755} & \mc{1}{r}{1.880} & \mc{1}{r}{-0.631} & \mc{1}{r}{41,208} \\  

    \mc{1}{l|}{var5} & \mc{1}{r}{-2.043} & \mc{1}{r}{-0.785} & \mc{1}{r}{-0.716} & \mc{1}{r}{0.186} & \mc{1}{r}{24,782} \\  

    \mc{1}{l|}{var6} & \mc{1}{r}{1.230} & \mc{1}{r}{0.567} & \mc{1}{r}{0.481} & \mc{1}{r}{-0.480} & \mc{1}{r}{43,490} \\  

    \mc{1}{l|}{var7} & \mc{1}{r}{-0.566} & \mc{1}{r}{1.739} & \mc{1}{r}{0.315} & \mc{1}{r}{-0.856} & \mc{1}{r}{39,933} \\  

    \mc{1}{l|}{var8} & \mc{1}{r}{1.045} & \mc{1}{r}{0.527} & \mc{1}{r}{-0.387} & \mc{1}{r}{1.670} & \mc{1}{r}{63,132} \\  

    \mc{1}{l|}{var9} & \mc{1}{r}{-0.239} & \mc{1}{r}{-0.360} & \mc{1}{r}{1.122} & \mc{1}{r}{-0.181} & \mc{1}{r}{56,453} \\  

  \end{longtabu}
    \begin{tablenotes}
    \scriptsize
    \item Footnote for a long table.
    \end{tablenotes}
  \end{ThreePartTable}

\end{landscape}

Indentation

PyTabular tries to indent the tables nicely, however you can eliminate indenting or change the indent width.


In [20]:
longtable.set_indent(0)
print(longtable)


\begin{landscape}

\begin{ThreePartTable}
\begin{longtabu}{cccccc}

\centering \\
\captionsetup{singlelinecheck=false,justification=centering}
\caption{Table 1 \label{table1}} \\
 & \mc{2}{c}{\textbf{\Large{Treated}}} & \mc{2}{c}{\textbf{\Large{Control}}} &  \\ 
\cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

\rotatebox{45}{\emph{Measure}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Observations}} \\[0.3cm] 
\hline \hline  

\endfirsthead

\mc{6}{c}{\tablename\ \thetable\ -- \emph{Continued from previous page}} \\
 & \mc{2}{c}{\textbf{\Large{Treated}}} & \mc{2}{c}{\textbf{\Large{Control}}} &  \\ 
\cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

\rotatebox{45}{\emph{Measure}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Observations}} \\[0.3cm] 
\hline \hline  

\endhead

\mc{6}{r}{\emph{Continued on next page}} \\

\endfoot
\endlastfoot

\\[0.3cm]
\mc{1}{l|}{var0} & \mc{1}{r}{-0.517} & \mc{1}{r}{0.879} & \mc{1}{r}{-0.235} & \mc{1}{r}{-1.171} & \mc{1}{r}{28,310} \\  

\mc{1}{l|}{var1} & \mc{1}{r}{1.277} & \mc{1}{r}{-2.389} & \mc{1}{r}{0.145} & \mc{1}{r}{-0.698} & \mc{1}{r}{81,208} \\  

\mc{1}{l|}{var2} & \mc{1}{r}{-0.918} & \mc{1}{r}{-0.487} & \mc{1}{r}{1.615} & \mc{1}{r}{0.669} & \mc{1}{r}{63,223} \\  

\mc{1}{l|}{\cellcolor{gray!40}{var3}} & \mc{1}{r}{\cellcolor{gray!40}{-0.398}} & \mc{1}{r}{\cellcolor{gray!40}{0.257}} & \mc{1}{r}{\cellcolor{gray!40}{-0.650}} & \mc{1}{r}{\cellcolor{gray!40}{-0.041}} & \mc{1}{r}{\cellcolor{gray!40}{22,335}} \\  

\mc{1}{l|}{var4} & \mc{1}{r}{-0.041} & \mc{1}{r}{0.755} & \mc{1}{r}{1.880} & \mc{1}{r}{-0.631} & \mc{1}{r}{41,208} \\  

\mc{1}{l|}{var5} & \mc{1}{r}{-2.043} & \mc{1}{r}{-0.785} & \mc{1}{r}{-0.716} & \mc{1}{r}{0.186} & \mc{1}{r}{24,782} \\  

\mc{1}{l|}{var6} & \mc{1}{r}{1.230} & \mc{1}{r}{0.567} & \mc{1}{r}{0.481} & \mc{1}{r}{-0.480} & \mc{1}{r}{43,490} \\  

\mc{1}{l|}{var7} & \mc{1}{r}{-0.566} & \mc{1}{r}{1.739} & \mc{1}{r}{0.315} & \mc{1}{r}{-0.856} & \mc{1}{r}{39,933} \\  

\mc{1}{l|}{var8} & \mc{1}{r}{1.045} & \mc{1}{r}{0.527} & \mc{1}{r}{-0.387} & \mc{1}{r}{1.670} & \mc{1}{r}{63,132} \\  

\mc{1}{l|}{var9} & \mc{1}{r}{-0.239} & \mc{1}{r}{-0.360} & \mc{1}{r}{1.122} & \mc{1}{r}{-0.181} & \mc{1}{r}{56,453} \\  

\end{longtabu}
\begin{tablenotes}
\scriptsize
\item Footnote for a long table.
\end{tablenotes}
\end{ThreePartTable}

\end{landscape}

In [21]:
longtable.set_indent(4)
print(longtable)


\begin{landscape}

    \begin{ThreePartTable}
    \begin{longtabu}{cccccc}

        \centering \\
        \captionsetup{singlelinecheck=false,justification=centering}
        \caption{Table 1 \label{table1}} \\
         & \mc{2}{c}{\textbf{\Large{Treated}}} & \mc{2}{c}{\textbf{\Large{Control}}} &  \\ 
        \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

        \rotatebox{45}{\emph{Measure}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Observations}} \\[0.3cm] 
        \hline \hline  

        \endfirsthead

        \mc{6}{c}{\tablename\ \thetable\ -- \emph{Continued from previous page}} \\
         & \mc{2}{c}{\textbf{\Large{Treated}}} & \mc{2}{c}{\textbf{\Large{Control}}} &  \\ 
        \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

        \rotatebox{45}{\emph{Measure}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Observations}} \\[0.3cm] 
        \hline \hline  

        \endhead

        \mc{6}{r}{\emph{Continued on next page}} \\

        \endfoot
        \endlastfoot

        \\[0.3cm]
        \mc{1}{l|}{var0} & \mc{1}{r}{-0.517} & \mc{1}{r}{0.879} & \mc{1}{r}{-0.235} & \mc{1}{r}{-1.171} & \mc{1}{r}{28,310} \\  

        \mc{1}{l|}{var1} & \mc{1}{r}{1.277} & \mc{1}{r}{-2.389} & \mc{1}{r}{0.145} & \mc{1}{r}{-0.698} & \mc{1}{r}{81,208} \\  

        \mc{1}{l|}{var2} & \mc{1}{r}{-0.918} & \mc{1}{r}{-0.487} & \mc{1}{r}{1.615} & \mc{1}{r}{0.669} & \mc{1}{r}{63,223} \\  

        \mc{1}{l|}{\cellcolor{gray!40}{var3}} & \mc{1}{r}{\cellcolor{gray!40}{-0.398}} & \mc{1}{r}{\cellcolor{gray!40}{0.257}} & \mc{1}{r}{\cellcolor{gray!40}{-0.650}} & \mc{1}{r}{\cellcolor{gray!40}{-0.041}} & \mc{1}{r}{\cellcolor{gray!40}{22,335}} \\  

        \mc{1}{l|}{var4} & \mc{1}{r}{-0.041} & \mc{1}{r}{0.755} & \mc{1}{r}{1.880} & \mc{1}{r}{-0.631} & \mc{1}{r}{41,208} \\  

        \mc{1}{l|}{var5} & \mc{1}{r}{-2.043} & \mc{1}{r}{-0.785} & \mc{1}{r}{-0.716} & \mc{1}{r}{0.186} & \mc{1}{r}{24,782} \\  

        \mc{1}{l|}{var6} & \mc{1}{r}{1.230} & \mc{1}{r}{0.567} & \mc{1}{r}{0.481} & \mc{1}{r}{-0.480} & \mc{1}{r}{43,490} \\  

        \mc{1}{l|}{var7} & \mc{1}{r}{-0.566} & \mc{1}{r}{1.739} & \mc{1}{r}{0.315} & \mc{1}{r}{-0.856} & \mc{1}{r}{39,933} \\  

        \mc{1}{l|}{var8} & \mc{1}{r}{1.045} & \mc{1}{r}{0.527} & \mc{1}{r}{-0.387} & \mc{1}{r}{1.670} & \mc{1}{r}{63,132} \\  

        \mc{1}{l|}{var9} & \mc{1}{r}{-0.239} & \mc{1}{r}{-0.360} & \mc{1}{r}{1.122} & \mc{1}{r}{-0.181} & \mc{1}{r}{56,453} \\  

    \end{longtabu}
        \begin{tablenotes}
        \scriptsize
        \item Footnote for a long table.
        \end{tablenotes}
    \end{ThreePartTable}

\end{landscape}

Advanced Merging

We can merge across rows and columns simultaneously. In LateX, these means nesting \multirow with \multicolumn. Lets modify the last two rows of table to demonstrate. In this exercise, lets change the last two rows as if we wanted them to display a fit statistic.


In [22]:
table[-2,0].set_content('$R^2$') #changing the content cell in the 2nd to last row, first column
table[-2:,0].merge(force=True) #merging over contents (must specify force=True)
table[-2:,1:].merge(force=True) #merging the data together (across rows and columns)
table[-2,1].set_alignment('c')
print(table)


\begin{table}\raggedright
\captionsetup{singlelinecheck=false,justification=raggedright}
\caption{A Table with Numbers \label{tab:table1}}

  \begin{ThreePartTable}
  \begin{tabu}{cccccc}

     & \mc{2}{c}{\textbf{\Large{Treated}}} & \mc{2}{c}{\textbf{\Large{Control}}} &  \\ 
    \cmidrule(lr){2-3} \cmidrule(lr){4-5}\morecmidrules\cmidrule(lr){4-5} 

    \rotatebox{45}{\emph{Measure}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Male}} & \rotatebox{45}{\emph{Female}} & \rotatebox{45}{\emph{Observations}} \\[0.3cm] 
    \hline \hline  

    \\[0.3cm]
    \mc{1}{l|}{var0} & \mc{1}{r}{-0.517} & \mc{1}{r}{0.879} & \mc{1}{r}{-0.235} & \mc{1}{r}{-1.171} & \mc{1}{r}{28,310} \\  

    \mc{1}{l|}{var1} & \mc{1}{r}{1.277} & \mc{1}{r}{-2.389} & \mc{1}{r}{0.145} & \mc{1}{r}{-0.698} & \mc{1}{r}{81,208} \\  

    \mc{1}{l|}{var2} & \mc{1}{r}{-0.918} & \mc{1}{r}{-0.487} & \mc{1}{r}{1.615} & \mc{1}{r}{0.669} & \mc{1}{r}{63,223} \\  

    \mc{1}{l|}{\cellcolor{gray!40}{var3}} & \mc{1}{r}{\cellcolor{gray!40}{-0.398}} & \mc{1}{r}{\cellcolor{gray!40}{0.257}} & \mc{1}{r}{\cellcolor{gray!40}{-0.650}} & \mc{1}{r}{\cellcolor{gray!40}{-0.041}} & \mc{1}{r}{\cellcolor{gray!40}{22,335}} \\  

    \mc{1}{l|}{var4} & \mc{1}{r}{-0.041} & \mc{1}{r}{0.755} & \mc{1}{r}{1.880} & \mc{1}{r}{-0.631} & \mc{1}{r}{41,208} \\  

    \mc{1}{l|}{var5} & \mc{1}{r}{-2.043} & \mc{1}{r}{-0.785} & \mc{1}{r}{-0.716} & \mc{1}{r}{0.186} & \mc{1}{r}{24,782} \\  

    \mc{1}{l|}{var6} & \mc{1}{r}{1.230} & \mc{1}{r}{0.567} & \mc{1}{r}{0.481} & \mc{1}{r}{-0.480} & \mc{1}{r}{43,490} \\  

    \mc{1}{l|}{var7} & \mc{1}{r}{-0.566} & \mc{1}{r}{1.739} & \mc{1}{r}{0.315} & \mc{1}{r}{-0.856} & \mc{1}{r}{39,933} \\  

    \mc{1}{l|}{\mr{2}{*}{$R^2$}} & \mc{5}{c}{\mr{2}{*}{1.045}} \\  

    \mc{1}{l|}{} & \mc{5}{r}{} \\  

  \end{tabu}
    \begin{tablenotes}
    \scriptsize
    \item This is a footnote
    \item This is another footnote
    \item [1]This footnote has a superscript
    \end{tablenotes}
  \end{ThreePartTable}

\end{table}
/home/jake/Documents/repos/erc/erc-tools/pytabular/pytabular/tables.py:274: UserWarning: Special character "$" found in cell (10, 0),
special characters may cause LateX errors, use remove_character() to remove
  warnings.warn(msg, UserWarning)
/home/jake/Documents/repos/erc/erc-tools/pytabular/pytabular/tables.py:274: UserWarning: Special character "^" found in cell (10, 0),
special characters may cause LateX errors, use remove_character() to remove
  warnings.warn(msg, UserWarning)

Warnings

You may have noticed the special character warnings above. PyTabular is not smart, and if you use special characters (e.g. '&', '%', '#', '_', '{', '}', '$', '\', '~', '^') in a cell it will not fix the cell if you have used special characters inappropriately. However, it will warn you when it spots these characters and you can remove these characters using the remove_character method. Otherwise, we trust you know LateX well enough to use these special characters correctly.