# Current state and the future of PrettyTables.jl

**URL:** <https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455>\
**Category:** Package Announcements\
**Tags:** prettytables\
**Created:** [August 21, 2024, 2:18pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455 "2024-08-21T14:18:22Z")\
**Posts on this page:** 20\
**Page:** 5

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [September 12, 2024, 3:02pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/81 "2024-09-12T15:02:25Z")

</div>

Sure

> **See below**
>
> ```julia
> \documentclass[12pt]{article}
> \usepackage[utf8]{inputenc}
> \usepackage{geometry}
> \usepackage{adjustbox}
> \geometry{margin = 1in}
> 
> \begin{document}
> 
> \begin{table}
> \centering
> \caption{Table is too big}
> % This would be \input{path/to/table.tex} normally
> \begin{tabular}{rrrrrrrr}
> \hline
> \textbf{Variable} & \textbf{Column 1} & \textbf{Column 2} & \textbf{Column 3} & \textbf{Column 4} & \textbf{Column 5} & \textbf{Column 6} & \textbf{Column 7} \\\hline
> Row label 1 & 0.01 & 0.02 & 0.03 & 0.04 & 0.05 & 0.06 & 0.07 \\
> Row label 2 & 0.1 & 0.2 & 0.3 & 0.4 & 0.5 & 0.6 & 0.7 \\
> Row label 3 & 1.0 & 2.0 & 3.0 & 4.0 & 5.0 & 6.0 & 7.0 \\
> Row label 4 & 10.0 & 20.0 & 30.0 & 40.0 & 50.0 & 60.0 & 70.0 \\
> Row label 5 & 100.0 & 200.0 & 300.0 & 400.0 & 500.0 & 600.0 & 700.0 \\
> Row label 6 & 1000.0 & 2000.0 & 3000.0 & 4000.0 & 5000.0 & 6000.0 & 7000.0 \\
> Row label 7 & 10000.0 & 20000.0 & 30000.0 & 40000.0 & 50000.0 & 60000.0 & 70000.0 \\
> Row label 8 & 100000.0 & 200000.0 & 300000.0 & 400000.0 & 500000.0 & 600000.0 & 700000.0 \\
> Row label 9 & 1.0e6 & 2.0e6 & 3.0e6 & 4.0e6 & 5.0e6 & 6.0e6 & 7.0e6 \\
> Row label 10 & 1.0e7 & 2.0e7 & 3.0e7 & 4.0e7 & 5.0e7 & 6.0e7 & 7.0e7 \\\hline
> \end{tabular}
> \end{table}
> 
> \begin{table}
> \centering
> \caption{Table is correct size}
> \adjustbox{width = \textwidth}{
> \begin{tabular}{rrrrrrrr}
> \hline
> \textbf{Variable} & \textbf{Column 1} & \textbf{Column 2} & \textbf{Column 3} & \textbf{Column 4} & \textbf{Column 5} & \textbf{Column 6} & \textbf{Column 7} \\\hline
> Row label 1 & 0.01 & 0.02 & 0.03 & 0.04 & 0.05 & 0.06 & 0.07 \\
> Row label 2 & 0.1 & 0.2 & 0.3 & 0.4 & 0.5 & 0.6 & 0.7 \\
> Row label 3 & 1.0 & 2.0 & 3.0 & 4.0 & 5.0 & 6.0 & 7.0 \\
> Row label 4 & 10.0 & 20.0 & 30.0 & 40.0 & 50.0 & 60.0 & 70.0 \\
> Row label 5 & 100.0 & 200.0 & 300.0 & 400.0 & 500.0 & 600.0 & 700.0 \\
> Row label 6 & 1000.0 & 2000.0 & 3000.0 & 4000.0 & 5000.0 & 6000.0 & 7000.0 \\
> Row label 7 & 10000.0 & 20000.0 & 30000.0 & 40000.0 & 50000.0 & 60000.0 & 70000.0 \\
> Row label 8 & 100000.0 & 200000.0 & 300000.0 & 400000.0 & 500000.0 & 600000.0 & 700000.0 \\
> Row label 9 & 1.0e6 & 2.0e6 & 3.0e6 & 4.0e6 & 5.0e6 & 6.0e6 & 7.0e6 \\
> Row label 10 & 1.0e7 & 2.0e7 & 3.0e7 & 4.0e7 & 5.0e7 & 6.0e7 & 7.0e7 \\\hline
> \end{tabular}
> } % adjustbox
> \end{table}
> 
> \end{document}
> 
> </details>
> ```

---

<div class="post-metadata">

**Author:** ![lrnv](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lrnv/32/19373_2.png) [@lrnv](https://discourse.julialang.org/u/lrnv)\
**Post date:** [September 12, 2024, 3:04pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/82 "2024-09-12T15:04:41Z")

</div>

Are you sure you pasted the right version ? This looks like what i have at the moment, that is not adjust to line size 🙂

errrr: saw your edit.

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [September 12, 2024, 3:05pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/83 "2024-09-12T15:05:40Z")

</div>

The edit shouldn’t change that. I’m not sure what “adjusting the font to line size” means, I thought the problem you were trying to solve is putting everything on one page.

---

<div class="post-metadata">

**Author:** ![lrnv](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lrnv/32/19373_2.png) [@lrnv](https://discourse.julialang.org/u/lrnv)\
**Post date:** [September 12, 2024, 4:17pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/84 "2024-09-12T16:17:10Z")

</div>

Ok @pdeffebach i’ve managed to test it. It’s not as good as the text size inside the table is also zoomed in right ? Can you make it with constant font size ? The problem is not putting everything on one page, but the other way around: I have small tables that i want to span \textwidth, but here they end up with a font that is maybe 25pt and thus this is not a solution for me 🤣

---

<div class="post-metadata">

**Author:** ![lrnv](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lrnv/32/19373_2.png) [@lrnv](https://discourse.julialang.org/u/lrnv)\
**Post date:** [September 12, 2024, 4:42pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/85 "2024-09-12T16:42:15Z")

</div>

@Ronis_BR, @pdeffebach I solve my issue using type piracy and replacement in the output, which feels very wrong but in the context of me and myself is good enough. In case someone wanders, I used:

```julia
function PrettyTables._latex_alignment(s::Symbol)
    if (s == :l) || (s == :L)
        return "l"
    elseif (s == :c) || (s == :C)
        return "c"
    elseif (s == :r) || (s == :R)
        return "r"
    elseif (s == :X)
        return "X" ### I simply added this case
    else
        error("Invalid LaTeX alignment symbol: $s.")
    end
end

function save_table(tbl, filename)
    open(filename, "w") do f
        pretty_table(
            ... # all others arguments. 
            alignment=:X,
        )
    end
    s = read(filename, String)
    write(filename, replace(s, "\\begin{tabular}" => "\\begin{tabularx}{\\linewidth}", "\\end{tabular}" => "\\end{tabularx}"))
end

```

---

<div class="post-metadata">

**Author:** ![floswald](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/floswald/32/195_2.png) [@floswald](https://discourse.julialang.org/u/floswald)\
**Post date:** [September 12, 2024, 8:19pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/86 "2024-09-12T20:19:07Z")

</div>

I use LaTeXTabulars.jl for that exact purpose. No fuzz.  
(PrettyTables.jl is amazing)

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [September 12, 2024, 8:26pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/87 "2024-09-12T20:26:48Z")

</div>

That certainly beats my current method of `raw""" """` and then a bunch of replacing for custom tables that can’t be made with PrettyTables! Thanks! I will start using this.

---

<div class="post-metadata">

**Author:** ![lrnv](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lrnv/32/19373_2.png) [@lrnv](https://discourse.julialang.org/u/lrnv)\
**Post date:** [September 12, 2024, 10:17pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/88 "2024-09-12T22:17:04Z")

</div>

> [@floswald](#):
>
> I use [LaTeXTabulars.jl](https://juliahub.com/ui/Packages/General/LaTeXTabulars) for that exact purpose. No fuzz.  
> ([PrettyTables.jl](https://juliahub.com/ui/Packages/General/PrettyTables) is amazing)

That was part of mty previous question about how much can `PrettyTables.jl` do 🙂

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [September 15, 2024, 9:13pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/89 "2024-09-15T21:13:33Z")

</div>

And after soooo many years, we finally can merge cells at the table header 🙂

 ![Captura de Tela 2024-09-15 às 18.13.21](https://global.discourse-cdn.com/julialang/original/3X/3/6/365bcefd8954fbd10d63890dfc776a3051de0a88.png)

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [September 15, 2024, 9:30pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/90 "2024-09-15T21:30:41Z")

</div>

How deeply can those column and row headers nest? Eg can there be Group 1.i.a, Group 1.ii.a etc?

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [September 15, 2024, 11:57pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/91 "2024-09-15T23:57:02Z")

</div>

You can have as many column labels as you like as merge than without restrictions (rows only).

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [September 16, 2024, 12:12pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/92 "2024-09-16T12:12:32Z")

</div>

@jar1 if you want to try, clone `v3` branch and the code is:

```julia
using PrettyTables

column_labels = [
    ["" for _ in 1:6],
    ["" for _ in 1:6],
    ["Test $i" for i in 1:6]
]

column_label_alignment = :c

merge_column_label_cells = [
    MergeCells(1, 1, 4, "Group #1", :c)
    MergeCells(1, 5, 2, "Group #2", :c)
    MergeCells(2, 1, 2, "Group #1.1", :c)
    MergeCells(2, 3, 2, "Group #1.2", :c)
]

summary_rows = [
    (data, i) -> sum(data[i, :]) / length(data[i, :])
]

summary_row_labels = [
    "Mean"
]

A = randn(10, 6)

tf = TextTableFormat(
    suppress_vertical_lines_at_column_labels = true,
    right_vertical_lines_at_data_columns = :none
)

pretty_table(
    A;
    column_labels,
    column_label_alignment,
    merge_column_label_cells,
    show_row_number_column = true,
    summary_rows,
    summary_row_labels,
    tf
)

```

 ![Captura de Tela 2024-09-16 às 09.12.15](https://global.discourse-cdn.com/julialang/original/3X/e/1/e10e077e44aefbb458d5ad11a662baac27ab71fb.png)

The only point is that I decided for an API very different from R’s gt package. Here, you have to “design” the labels yourself. See how you need to add the blank fields, allowing to merge the cells. However, in this case, we have much more flexibility, since we can merge cells below the topmost one.

In the future, we might provide a macro or something for assisting in the design.

EDIT: Ah btw, I assume the terminal supports rendering underlines. Otherwise you will not get the “border” below the merged cell. We could add a new line, but it will lead to an extremely complicated API to select which cells you want a line and which cells you do not want.

---

<div class="post-metadata">

**Author:** ![barucden](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/barucden/32/26154_2.png) [@barucden](https://discourse.julialang.org/u/barucden)\
**Post date:** [September 16, 2024, 12:35pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/93 "2024-09-16T12:35:02Z")

</div>

First of all, thank you for the package! I think you are doing an amazing job.

Influenced by LaTeX, I can’t help but wonder, why not go for column label definition similar to

```julia
column_labels = [
  MultiCol(1:4, "Group 1") MultiCol(5:8, "Group 2");
  MultiCol(1:2, "Group 1.I") MultiCol(3:4, "Group 1.II") MultiCol(5:6, "Group 2.I") MultiCol(7:8, "Group 2.II");
  "Group 1.I.a" "Group 1.I.b" "Group 1.II.a" "Group 1.II.b" "Group 2.I.a" "Group 2.I.b" "Group 2.II a" "Group 2.II.b"
]

```

which would result in the following table header:

```julia
=============================================================================================================
Group 1 Group 2
----------------------------------------------------- ------------------------------------------------------
Group 1.I Group 1.II Group 2.I Group 2.II
------------------------ --------------------------- ------------------------- ---------------------------
Group 1.I.a Group 1.I.b Group 1.II.a Group 1.II.b Group 2.I.a Group 2.I.b Group 2.II a Group 2.II.b
=============================================================================================================

```

It feels like a more convenient API to me (although that might be due to my familiarity with LaTeX). I have never written a table-formatting package so I am not aware of possible issues. I am genuinely asking.

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [September 16, 2024, 12:42pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/94 "2024-09-16T12:42:42Z")

</div>

There is only one problem. In this case, you will not be able to merge cells when you have a pre-defined column labels unless you rewrite the entire column label vector.

For example, in DataFrames, you have the row names and row types. In the current approach, we can, for example, merge some cells there. If we change to that approach, we must rewrite the entire vector as DataFrames does.

However, we can add a macro to provide the correct vectors, allowing the best of both worlds.

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [September 16, 2024, 12:46pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/95 "2024-09-16T12:46:49Z")

</div>

However, I think I will use your design regarding how to specify the columns to be merged 🙂

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [September 16, 2024, 12:49pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/96 "2024-09-16T12:49:15Z")

</div>

Ah, there is another problem with that approach, the processing will be more difficult. In current case, we can loop through the column labels because it has the same number of columns as the table. In your case, it will not have. Hence, I will probably need to reprocess it inside the algorithm to avoid a huge modification in the printing state iterator. Thus, the macro is the best option here.

---

<div class="post-metadata">

**Author:** ![barucden](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/barucden/32/26154_2.png) [@barucden](https://discourse.julialang.org/u/barucden)\
**Post date:** [September 16, 2024, 12:57pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/97 "2024-09-16T12:57:48Z")

</div>

Okay, sure, I knew there would be some obstacles 🙂 I just wanted to bring it up in case you had not consider it.

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [September 16, 2024, 4:24pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/98 "2024-09-16T16:24:51Z")

</div>

@barucden

I would like to thank you for the suggestion! Your proposal gave me one very nice idea. We can allow `merge_column_label_cells = :auto`. In this case, PrettyTables automatic regenerates `column_labels` and `merge_column_label_cells` using the specification in `MultiColumn`.

It is important to not let it happen automatically. Let’s say we have a **very** big table (10\_000, 10\_000). In this case, the column labels can be generated by an iterator that does not allocate, like `1:10_000`. If we reprocess automatically, we will allocate an array with 10\_000 elements, leading to a huge slowdown. Thus, we only do this if the user wants.

The good side is that we can generate the same table using:

```julia
using PrettyTables

column_labels = [
    [MultiColumn(4, "Group #1"), MultiColumn(2, "Group #2")],
    [MultiColumn(2, "Group #1.1"), MultiColumn(2, "Group #1.2"), "", ""],
    ["Test $i" for i in 1:6],
]

column_label_alignment = :c

merge_column_label_cells = :auto

summary_rows = [
    (data, i) -> sum(data[i, :]) / length(data[i, :])
]

summary_row_labels = [
    "Mean"
]

A = randn(10, 6)

tf = TextTableFormat(
    suppress_vertical_lines_at_column_labels = true,
    right_vertical_lines_at_data_columns = :none
)

pretty_table(
    A;
    column_labels,
    column_label_alignment,
    merge_column_label_cells,
    show_row_number_column = true,
    summary_rows,
    summary_row_labels,
    tf
)

```

The `MultiColumn` has only the number of columns because the column index is given by the position in the array. Thus, I do not need to check consistency at this stage.

---

<div class="post-metadata">

**Author:** ![barucden](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/barucden/32/26154_2.png) [@barucden](https://discourse.julialang.org/u/barucden)\
**Post date:** [September 16, 2024, 5:03pm UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/99 "2024-09-16T17:03:53Z")

</div>

I cannot comment on the technical implications you mention, but that code feels very natural to me!

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [September 26, 2024, 12:11am UTC](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455/100 "2024-09-26T00:11:06Z")

</div>

Hi everyone!

Despite from very few niche features (like `autowrap`), the text back end is completed! Now I need to write the tests, which should take sometime…

I could re-implement all the features as we have now, including the custom text cells. I selected a more clean approach. Previously, I tried to cache as many things as I can, leading to a faster algorithm that allocates a lot and it is very difficult to maintain. Now, I try to cache almost nothing. Hence, in some cases we need to process the same thing twice. This approach reduces the allocation, but slightly increases the processing time. However, it turns out that this additional processing time is neglible for a package that print tables.

The good side is that we can now make tables like this one (yes, after typing a lot of things and tuning a lot of options 😅)

 ![Captura de Tela 2024-09-25 às 21.06.43](https://global.discourse-cdn.com/julialang/original/3X/b/f/bf78ad05f470ea14b78c9b4b26fcc7df8b03f2a8.png)

[Previous page](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455.md?page=4)

[Next page](https://discourse.julialang.org/t/current-state-and-the-future-of-prettytables-jl/118455.md?page=6)
