-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
ENH: Adding highlighting options to to_latex
function
#38328
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Looking through the discussion in #3196 it seems like there was interest in doing things like this but nobody found time to do the legwork. Would you be interested in submitting a PR? |
@yanaiela, it would be great if you would post the expected output latex code here. From my perspective highlighting the rows is quite doable thing. You refer to the best value. But what would it be? Should there be a function passed to define it? Therefore, please provide the latex code, or even better suggest some tests. |
Hey @arw2019, @ivanovmg, sorry for the late reply. I'd be happy to get this functionality first even without handling multiindex or multicolumn. Different people may have different functionalities in mind, but for me I'd say the multiindex should be highlighted based on the best value in each of these indices. For the best value, as I mentioned, I think it can be passed as an argument, since it can be either based on small or large values (but I can image other scenarios). So maybe the best way would be to support the more common usage of min and max (to my perspective) but also allow to pass a function that will be used instead? For an example: If currently a latex table would look like:
|
For anyone that came here like me looking for a temporary solution: On the Python side: from functools import partial
import pandas as pd
import numpy as np
def bold_formatter(x, value, num_decimals=2):
"""Format a number in bold when (almost) identical to a given value.
Args:
x: Input number.
value: Value to compare x with.
num_decimals: Number of decimals to use for output format.
Returns:
String converted output.
"""
# Consider values equal, when rounded results are equal
# otherwise, it may look surprising in the table where they seem identical
if round(x, num_decimals) == round(value, num_decimals):
return f"{{\\bfseries\\num{{{x:.{num_decimals}f}}}}}"
else:
return f"\\num{{{x:.{num_decimals}f}}}"
df = pd.DataFrame(np.array([[1.123456, 2.123456, 3.123456, 4.123456],
[11.123456, 22.123456, 33.123456, 44.123456],
[111.123456, 222.123456, 333.123456, 444.123456],]),
columns=['a', 'b', 'c', 'd'])
col_names = ['a in \\si{\\meter}',
'b in \\si{\\volt}',
'c in \\si{\\seconds}',
'd']
# Colums to format with maximum condition and 2 floating decimals
max_columns_2f = ['a']
# Colums to format with minimum condition and 2 floating decimals
min_columns_2f = ['b', 'c']
# Colums to format with minimum condition and 4 floating decimals
min_columns_4f= ['d']
fmts_max_2f = {column: partial(bold_formatter, value=df[column].max(), num_decimals=2) for column in max_columns_2f}
fmts_min_2f = {column: partial(bold_formatter, value=df[column].min(), num_decimals=2) for column in min_columns_2f}
fmts_min_4f = {column: partial(bold_formatter, value=df[column].min(), num_decimals=4) for column in min_columns_4f}
fmts = dict(**fmts_max_2f, **fmts_min_2f, **fmts_min_4f)
with open("test_table.tex", "w") as fh:
df.to_latex(buf=fh,
index=False,
header=col_names,
formatters=fmts,
escape=False) Of course, this could be made a bit shorter, however I believe this way it is still pretty readable which I think improves adaptability. In your LaTex code, use \usepackage{booktabs}
\usepackage{siunitx}
\begin{table}
\centering
\caption{Test table.}
\label{tab:test-table}
\input{test_table.tex}
\end{table} This should procude something like this: Using the |
For the min and max just use a function like that: min_pandas = df.min(1)
def f_tex(x):
if x in min_pandas.values:
return '\\textbf{' +f'{x:0.2f}'+ '}'
else:
return f'{x:0.2f}'
df.to_latex( buf = name, bold_rows =True, escape = False,
formatters = [f_tex]*len(df.columns)) Hope this could be helpful. |
@matteoguarrera this does not really do what it's supposed to.
so its formatting rows and not columns.
which does not make sense, neither row-, nor column-wise. |
@MaxSchambach
This is of course a specific example, but the entire functionality of Styler for CSS is being reproduced for use with LaTeX. |
Yes, looks promising! |
Is this possible in current version? |
Following #3196, it would be extremely useful to add the possibility of highlighting the best value in a row or column of a DataFrame object when converting into a latex table (the
to_latex
function)A convenient api for that would be to add a parameter to the
to_latex()
function, such ashighlight_rows=TYPE
, where TYPE can bebold|italics|...
and than each row's best value would be highlighted.There could also be a scenario where the best value is the lowest one, so maybe an additional parameter should be
best_highlight: str
betweenhigh|low
.The text was updated successfully, but these errors were encountered: