1

I would like to show a (LaTeX) table in a Matplotlib graph. I have generated the LaTeX source for the table by styling a Pandas DataFrame, and am attempting to add that to my graph using the Axes.text method. However, the code is failing with what seems to be some kind of LaTeX interpretation error.

Here's what I have:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

df = pd.DataFrame(np.random.randn(10000, 4) * np.array([1, 2, 2, 0.5]) + np.array([0, 4, 9, 11]), 
                  columns=['first', 'second', 'third', 'fourth'])

stats = df.describe()
stats.index = [idx.replace('%', 'p') for idx in stats.index]

styled = stats.style\
    .background_gradient(cmap=sns.blend_palette(['xkcd:red', 'white', 'xkcd:green'], as_cmap=True), 
                         vmin=-15, vmax=15, 
                         subset=pd.IndexSlice[['mean', 'min', '25p', '50p', '75p', 'max'], :])\
    .background_gradient(cmap=sns.blend_palette(['white', 'xkcd:purple'], as_cmap=True), 
                         vmin=0, vmax=3, subset=pd.IndexSlice['std', :])\
    .format(lambda v: f'{v:0.2f}')\
    .format(lambda v: f'{v:0.0f}', subset=pd.IndexSlice['count', :])

s = styled.to_latex(
    clines="skip-last;data",
    convert_css=True,
    position_float="centering",
    multicol_align="|c|",
    hrules=True
).replace('\n', ' ')

plt.rc('text', usetex=True)
plt.rc('text.latex', preamble=r'\usepackage{booktabs} \usepackage{etoolbox} \usepackage{multirow} \usepackage[table]{xcolor} \usepackage{colortbl} \usepackage{siunitx} \usepackage{longtable} \usepackage{graphics}')

fig, ax = plt.subplots(1, 1, figsize=(10, 6))
df.plot(kind='hist', ax=ax, histtype='stepfilled', alpha=0.4, bins=50)
ax.set_xlim([-6, 15])
ax.legend(loc='upper right')
ax.text(0.02, 0.98, s, ha='left', va='top', transform=ax.transAxes)

The graphing works fine except for the inclusion of the styled table. I get this result, which is clearly not correct.

Table w styling problems

I'm hoping for something more like this to show up on the Axes. Properly styled table

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
8one6
  • 13,078
  • 12
  • 62
  • 84
  • Might be easier to save the table as an image, and then show it on the figure with https://stackoverflow.com/q/65387500/7758804. It should be noted, that it will be confusing if the table uses colors similar to the plot (green and red) but those colors have different meanings than the legend. There's really not a good reason to color the summary statistics, particularly the way the highlighting is done. – Trenton McKinney Aug 28 '23 at 22:50
  • https://stackoverflow.com/a/63387275/7758804 is an option from 2020 fore exporting the styled table to an image. – Trenton McKinney Aug 28 '23 at 22:57
  • Appreciate the answers, but not looking for a workaround. Any idea why the table shows but doesn't seem to handle the color directives properly? – 8one6 Aug 28 '23 at 23:39
  • The latex is just a string, and matplotlib probably doesn't know how to render `{\\cellcolor[HTML]{73D076}} \\color[HTML]{000000} 9.00`. It seems you can do an image, as previously suggested, or a plain text table as shown in https://stackoverflow.com/a/8531491/7758804 – Trenton McKinney Aug 29 '23 at 00:23
  • Also, I see https://stackoverflow.com/q/68196610/7758804, but this is a table, below a plot. – Trenton McKinney Aug 29 '23 at 00:25
  • I hope this is not a too stupid question but, as it is [said in the documentation](https://matplotlib.org/stable/tutorials/text/usetex.html) do you have a functional LaTeX installation and if you are in Windows, is it in the PATH? – EvensF Aug 29 '23 at 01:57
  • Yes, it's functional. Note that there is indeed some LaTeX rendering happening in the upper-left of the axes area. It's just not handling the cell coloring correctly. – 8one6 Aug 29 '23 at 03:11
  • Can confirm the `s` string does compile fine with colors, but not inside matplotlib – paime Aug 29 '23 at 08:41
  • A simple `plt.text(0.5, 0.5, r"${ \color[HTML]{AA54AA} \textrm{This is some text} }$")` does not work also, but works if creating a file with `plt.savefig("fig.ps")`, see [related stackoverflow post](https://stackoverflow.com/questions/55310241/latex-colors-not-rendered-in-matplotlib-text). – paime Aug 29 '23 at 08:59
  • @paime can you confirm whether you can get my full example to work with the `ps` trick? – 8one6 Aug 29 '23 at 12:17
  • unfortunately the full example didn't work with ps trick, I didn't look further though – paime Aug 29 '23 at 12:18
  • seems to come from the `position_float` arg of the `styled.to_latex()`, if you remove it it works, but font seems not applied, idk why – paime Aug 29 '23 at 12:27
  • and say I need something more "normal" than `.ps` as my output format...if I replace the "save as .ps" with "save as .pdf" it doesn't work. Very frustrating! Is there a way to convert the ps to an image file in a second step that won't break it? I'll add a bounty to this tomorrow, but would love to know, behind the scenes, why this doesn't "just work". – 8one6 Aug 29 '23 at 16:13

0 Answers0