Skip to content

Commit df7277c

Browse files
authored
DOC: comprehensive example of Styler.to_latex features (#45228)
1 parent e69e97f commit df7277c

File tree

3 files changed

+118
-0
lines changed

3 files changed

+118
-0
lines changed
96.9 KB
Loading
Loading

pandas/io/formats/style.py

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,124 @@ def to_latex(
835835
{} & {0} \\
836836
0 & {\bfseries}{\Huge{1}} \\
837837
\end{tabular}
838+
839+
Examples
840+
--------
841+
Below we give a complete step by step example adding some advanced features
842+
and noting some common gotchas.
843+
844+
First we create the DataFrame and Styler as usual, including MultiIndex rows
845+
and columns, which allow for more advanced formatting options:
846+
847+
>>> cidx = pd.MultiIndex.from_arrays([
848+
... ["Equity", "Equity", "Equity", "Equity",
849+
... "Stats", "Stats", "Stats", "Stats", "Rating"],
850+
... ["Energy", "Energy", "Consumer", "Consumer", "", "", "", "", ""],
851+
... ["BP", "Shell", "H&M", "Unilever",
852+
... "Std Dev", "Variance", "52w High", "52w Low", ""]
853+
... ])
854+
>>> iidx = pd.MultiIndex.from_arrays([
855+
... ["Equity", "Equity", "Equity", "Equity"],
856+
... ["Energy", "Energy", "Consumer", "Consumer"],
857+
... ["BP", "Shell", "H&M", "Unilever"]
858+
... ])
859+
>>> styler = pd.DataFrame([
860+
... [1, 0.8, 0.66, 0.72, 32.1678, 32.1678**2, 335.12, 240.89, "Buy"],
861+
... [0.8, 1.0, 0.69, 0.79, 1.876, 1.876**2, 14.12, 19.78, "Hold"],
862+
... [0.66, 0.69, 1.0, 0.86, 7, 7**2, 210.9, 140.6, "Buy"],
863+
... [0.72, 0.79, 0.86, 1.0, 213.76, 213.76**2, 2807, 3678, "Sell"],
864+
... ], columns=cidx, index=iidx).style
865+
866+
Second we will format the display and, since our table is quite wide, will
867+
hide the repeated level-0 of the index:
868+
869+
>>> styler.format(subset="Equity", precision=2)
870+
... .format(subset="Stats", precision=1, thousands=",")
871+
... .format(subset="Rating", formatter=str.upper)
872+
... .format_index(escape="latex", axis=1)
873+
... .format_index(escape="latex", axis=0)
874+
... .hide(level=0, axis=0) # doctest: +SKIP
875+
876+
Note that one of the string entries of the index and column headers is "H&M".
877+
Without applying the `escape="latex"` option to the `format_index` method the
878+
resultant LaTeX will fail to render, and the error returned is quite
879+
difficult to debug. Using the appropriate escape the "&" is converted to "\\&".
880+
881+
Thirdly we will apply some (CSS-HTML) styles to our object. We will use a
882+
builtin method and also define our own method to highlight the stock
883+
recommendation:
884+
885+
>>> def rating_color(v):
886+
... if v == "Buy": color = "#33ff85"
887+
... elif v == "Sell": color = "#ff5933"
888+
... else: color = "#ffdd33"
889+
... return f"color: {color}; font-weight: bold;"
890+
>>> styler.background_gradient(cmap="inferno", subset="Equity", vmin=0, vmax=1)
891+
... .applymap(rating_color, subset="Rating") # doctest: +SKIP
892+
893+
All the above styles will work with HTML (see below) and LaTeX upon conversion:
894+
895+
.. figure:: ../../_static/style/latex_stocks_html.png
896+
897+
However, we finally want to add one LaTeX only style
898+
(from the {graphicx} package), that is not easy to convert from CSS and
899+
pandas does not support it. Notice the `--latex` flag used here,
900+
as well as `--rwrap` to ensure this is formatted correctly and
901+
not ignored upon conversion.
902+
903+
>>> styler.applymap_index(
904+
... lambda v: "rotatebox:{45}--rwrap--latex;", level=2, axis=1
905+
... ) # doctest: +SKIP
906+
907+
Finally we render our LaTeX adding in other options as required:
908+
909+
>>> styler.to_latex(
910+
... caption="Selected stock correlation and simple statistics.",
911+
... clines="skip-last;data",
912+
... convert_css=True,
913+
... position_float="centering",
914+
... multicol_align="|c|",
915+
... hrules=True,
916+
... ) # doctest: +SKIP
917+
\begin{table}
918+
\centering
919+
\caption{Selected stock correlation and simple statistics.}
920+
\begin{tabular}{llrrrrrrrrl}
921+
\toprule
922+
& & \multicolumn{4}{|c|}{Equity} & \multicolumn{4}{|c|}{Stats} & Rating \\
923+
& & \multicolumn{2}{|c|}{Energy} & \multicolumn{2}{|c|}{Consumer} &
924+
\multicolumn{4}{|c|}{} & \\
925+
& & \rotatebox{45}{BP} & \rotatebox{45}{Shell} & \rotatebox{45}{H\&M} &
926+
\rotatebox{45}{Unilever} & \rotatebox{45}{Std Dev} & \rotatebox{45}{Variance} &
927+
\rotatebox{45}{52w High} & \rotatebox{45}{52w Low} & \rotatebox{45}{} \\
928+
\midrule
929+
\multirow[c]{2}{*}{Energy} & BP & {\cellcolor[HTML]{FCFFA4}}
930+
\color[HTML]{000000} 1.00 & {\cellcolor[HTML]{FCA50A}} \color[HTML]{000000}
931+
0.80 & {\cellcolor[HTML]{EB6628}} \color[HTML]{F1F1F1} 0.66 &
932+
{\cellcolor[HTML]{F68013}} \color[HTML]{F1F1F1} 0.72 & 32.2 & 1,034.8 & 335.1
933+
& 240.9 & \color[HTML]{33FF85} \bfseries BUY \\
934+
& Shell & {\cellcolor[HTML]{FCA50A}} \color[HTML]{000000} 0.80 &
935+
{\cellcolor[HTML]{FCFFA4}} \color[HTML]{000000} 1.00 &
936+
{\cellcolor[HTML]{F1731D}} \color[HTML]{F1F1F1} 0.69 &
937+
{\cellcolor[HTML]{FCA108}} \color[HTML]{000000} 0.79 & 1.9 & 3.5 & 14.1 &
938+
19.8 & \color[HTML]{FFDD33} \bfseries HOLD \\
939+
\cline{1-11}
940+
\multirow[c]{2}{*}{Consumer} & H\&M & {\cellcolor[HTML]{EB6628}}
941+
\color[HTML]{F1F1F1} 0.66 & {\cellcolor[HTML]{F1731D}} \color[HTML]{F1F1F1}
942+
0.69 & {\cellcolor[HTML]{FCFFA4}} \color[HTML]{000000} 1.00 &
943+
{\cellcolor[HTML]{FAC42A}} \color[HTML]{000000} 0.86 & 7.0 & 49.0 & 210.9 &
944+
140.6 & \color[HTML]{33FF85} \bfseries BUY \\
945+
& Unilever & {\cellcolor[HTML]{F68013}} \color[HTML]{F1F1F1} 0.72 &
946+
{\cellcolor[HTML]{FCA108}} \color[HTML]{000000} 0.79 &
947+
{\cellcolor[HTML]{FAC42A}} \color[HTML]{000000} 0.86 &
948+
{\cellcolor[HTML]{FCFFA4}} \color[HTML]{000000} 1.00 & 213.8 & 45,693.3 &
949+
2,807.0 & 3,678.0 & \color[HTML]{FF5933} \bfseries SELL \\
950+
\cline{1-11}
951+
\bottomrule
952+
\end{tabular}
953+
\end{table}
954+
955+
.. figure:: ../../_static/style/latex_stocks.png
838956
"""
839957
obj = self._copy(deepcopy=True) # manipulate table_styles on obj, not self
840958

0 commit comments

Comments
 (0)