# How to colour individual array entries in a DataFrame cell with PrettyTables or similar?

**URL:** <https://discourse.julialang.org/t/how-to-colour-individual-array-entries-in-a-dataframe-cell-with-prettytables-or-similar/102157>\
**Category:** General Usage\
**Tags:** question, package, dataframes, tables, prettytables\
**Created:** [July 27, 2023, 2:02pm UTC](https://discourse.julialang.org/t/how-to-colour-individual-array-entries-in-a-dataframe-cell-with-prettytables-or-similar/102157 "2023-07-27T14:02:07Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Olegg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/olegg/32/51316_2.png) [@Olegg](https://discourse.julialang.org/u/Olegg)\
**Post date:** [July 27, 2023, 2:02pm UTC](https://discourse.julialang.org/t/how-to-colour-individual-array-entries-in-a-dataframe-cell-with-prettytables-or-similar/102157/1 "2023-07-27T14:02:07Z")

</div>

I have a many-column DataFrames with most columns containing an array in each cell. (These are properties per solution in multi-constrained optimisation.) Here’s a snippet with 3-element arrays

 ![Snippit Results](https://global.discourse-cdn.com/julialang/original/3X/2/e/2e8cfb70648652f6e5919814e26ec409b93abf9a.png)

Would it be possible to colour negative array elements in Red, and perhaps assign another colour to elements for a grossly violated constraint?

- In the PrettyTables package (which is awesome!) I only see how to Highlight the whole array.

- Another option — split an array column into scalar subcolumns — seems unwieldy for a wide table

- There’s the LaTeX backend in PrettyTables, but I’d like to display the table in the terminal. So LaTeX textcolor commands are unlikely to work.

- Using an R or Python tables package, which seems OTT.

Is there another solution? Thanks!

Link: [PrettyTables announcement](https://discourse.julialang.org/t/ann-prettytables-jl-print-formatted-tables-in-julia/19550)

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [July 27, 2023, 6:01pm UTC](https://discourse.julialang.org/t/how-to-colour-individual-array-entries-in-a-dataframe-cell-with-prettytables-or-similar/102157/2 "2023-07-27T18:01:36Z")

</div>

@Ronis_BR is the best to answer this question 😄 so pinging him.

---

<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:** [July 27, 2023, 8:04pm UTC](https://discourse.julialang.org/t/how-to-colour-individual-array-entries-in-a-dataframe-cell-with-prettytables-or-similar/102157/3 "2023-07-27T20:04:33Z")

</div>

Hi @Olegg !

You can 😃, but not easily 😢

The problem is that PrettyTables.jl is not aware of the cell data. Otherwise, we would need to consider many possibilities. To print a cell with colors, we need to use `AnsiTextCell` in the original table. This value is necessary because we perform some in-place modifications to align things when you have escape sequences. Hence, the only possibility is if you transform the `DataFrame` into another table with the `AnsiTextCell`s and use `pretty_table` to print it. Here is an example:

```julia
using PrettyTables

df = DataFrame(a = [randn(3) for _ in 1:10], b = [randn(3) for _ in 1:10])

# This function re-implements the Julia array printing but adding escape sequences to
# colorize the output.
function colorize(v::AbstractVector)
    # Define the crayons.
    cred = string(crayon"bold red")
    creset = string(crayon"reset")

    # Print the array.
    ansi_str = "["

    for element in v
        v_str = sprint(print, element; context = :compact => true)

        if element < 0
            ansi_str *= cred * v_str * creset
        else
            ansi_str *= v_str
        end

        ansi_str *= ", "
    end

    ansi_str = chop(ansi_str; tail = 2) * "]"

    # Return the AnsiTextCell.
    return AnsiTextCell(ansi_str)
end

A = [colorize(df[i, j]) for i in 1:size(df, 1), j in 1:size(df, 2)]

pretty_table(
    A;
    alignment = :l,
    header = names(df),
    show_row_number = true,
    hlines = [:header],
    vlines = [1]
)

```

---

<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:** [July 27, 2023, 8:08pm UTC](https://discourse.julialang.org/t/how-to-colour-individual-array-entries-in-a-dataframe-cell-with-prettytables-or-similar/102157/4 "2023-07-27T20:08:50Z")

</div>

![shot](https://global.discourse-cdn.com/julialang/original/3X/9/7/975a854ae2df79f7766b03758433aa5a51e04dfa.png)

---

<div class="post-metadata">

**Author:** ![Olegg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/olegg/32/51316_2.png) [@Olegg](https://discourse.julialang.org/u/Olegg)\
**Post date:** [July 27, 2023, 8:15pm UTC](https://discourse.julialang.org/t/how-to-colour-individual-array-entries-in-a-dataframe-cell-with-prettytables-or-similar/102157/5 "2023-07-27T20:15:12Z")

</div>

Thank you – that’s perfect! It might be a good use case, as the red colour (without the minus) is common for negative numbers in applications.

Would something similar work with the HTML back-end in PrettyTables.jl ? (An excellent package, thanks!)

---

<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:** [July 28, 2023, 2:04am UTC](https://discourse.julialang.org/t/how-to-colour-individual-array-entries-in-a-dataframe-cell-with-prettytables-or-similar/102157/6 "2023-07-28T02:04:27Z")

</div>

Yes! In HTML is much easier because we can have HTML commands in cells if we set `allow_html_in_cells` to `true`. Hence, we only need a formatter:

```julia
ft = (v, i, j) -> begin
    # Print the array.
    str = "["

    for element in v
        v_str = sprint(print, element; context = :compact => true)

        if element < 0
            str *= "<span style=\"color: red\">" * v_str * "</span>"
        else
            str *= v_str
        end

        str *= ", "
    end

    str = chop(str; tail = 2) * "]"

    # Return the formatted text.
    return str
end

```

```julia
show(stdout, MIME("text/html"), df; formatters = ft, allow_html_in_cells = true)

```

 ![Captura de Tela 2023-07-27 às 22.04.13](https://global.discourse-cdn.com/julialang/original/3X/d/4/d424249636178f39474025db8ca772fd04d172b6.png)
