[ANN] PrettyTables.jl - Print formatted tables in Julia

Guys!

I needed to change the API because I wanted to support Crayons.jl. Now, every single styling is handle by Crayons.jl. The downside is that this is breaking (sorry…). The good side is that we have now many options to customize our tables, like changing the background to highlight rows and columns:

I did not tag a version yet and I would love some feedback before :slight_smile:

22 Likes

Beautiful!

1 Like

Hi guys!

I have updated the package (master) to support multiple lines in the cells. Hence, we can now have something like:

julia> data = Any[1.0 "Flag 1, Flag 2, Flag 3\nFlag 4, Flag 5, Flag 6, Flag 7";
                  2.0 "Flag 2, Flag 3, Flag 8\nFlag 10";
                  3.0 "Flag 4, Flag 6"];

julia> pretty_table(data, ["t" "Active flags"]; linebreaks=true, alignment=:l, hlines = [1,2,3])
β”Œβ”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ t   β”‚ Active flags                   β”‚
β”œβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 1.0 β”‚ Flag 1, Flag 2, Flag 3         β”‚
β”‚     β”‚ Flag 4, Flag 5, Flag 6, Flag 7 β”‚
β”œβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 2.0 β”‚ Flag 2, Flag 3, Flag 8         β”‚
β”‚     β”‚ Flag 10                        β”‚
β”œβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 3.0 β”‚ Flag 4, Flag 6                 β”‚
β””β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

I would appreciate if someone can test before I tag the new version :slight_smile:

6 Likes

I just noticed this package β€” it might be just what I was looking for. I looked in the documentation and didn’t see this there, but is it possible to print a custom row name rather than a row number?

Edit: I suppose it could be treated as just another column in this formulation.

1 Like

Yeah! Just use hcat and add whatever you want :slight_smile: Let me know if this works for you.

1 Like

image

Neat! :slight_smile:

Is there a way to make the elements of the first column bold to match the headers in the top row?

Edit: Ah, right, I should be able to do it with a Highlighter:

highlight_row_label = Highlighter(
    f=(data, i, j) -> j == 1,
    crayon=Crayon(bold=true)
)
1 Like

Yes, notice that a crayon can be created easier with just crayon"bold".

Oh, that’s really nice!

So I think I’ve found a possibly legitimate reason to want row labels β€” the row labels might be a different type than the array. And the array might be sparse, and there are currently some problems in Base with some operations on SparseArrays of type Any, which is what you’d get if the row labels were concatenated to the matrix. There’s also the performance impact of constructing the row-concatenated array purely for display purposes.

I also noticed that larger tables don’t get visually abbreviated, which may be a feature or a curse, depending on circumstance. :smiley:

My use case is for implementing the printing of a custom array type, which may get very large, so I’d need to edit down the printed array in some fashion.

Otherwise, things look good on master to me!

I think I found an escaping bug:

Yeah, I haven’t though yet what to do if the table is bigger than the display. When I have to print really long tables, I print to files and open in an editor without line wrapping.

I have to escape the string to avoid formatting problems. The Julia function escape_string automatically escape " by default. I have not idea how to easily fix that without introducing many other problems. For example, if I do not escape the string, a header with β€œ1234\t” will break the format of the table.

Any ideas?

Escaping usually depends on what you’re trying to accomplish – is the goal here to know how many on-screen characters each string takes up so that you can compute the layout parameters?

Yes it is. I need to compute the size of the each column.

Then you might be able to get away with simply stripping out characters of variable width (eg. strip(s, ['\t']). In ASCII I don’t know of any other than tab off the top of my head, so that might be a good start.

Escaping is also used e.g. in HTML to prevent accidental injection of content as code, but that’s a different use. In case that’s also useful for PrettyTables HTML display you can see how I implemented it in my Hyperscript package here and here.

The problem of selecting which characters to escape with string is that I may miss many more, like, for example, \e etc. That’s why escaping the entire string (like the display function of DataFrames do) seems more appropriate.

1 Like

Oh, I see. Thanks for that example. I’ll think about it and let you know if I come up with anything.

1 Like

You could print a subset of large tables in the REPL and use arrow keys to scroll around. REPGamesBase.jl has functionality for the key input.

2 Likes

Hi,

This is a really nice package. How do I print tables side by side.

Hi @sbk,

Thanks :slight_smile: In fact, we do not have support to print two tables side by side. Can you explain a little more what do you want to achieve?

Thanks for your reply. What I want is exactly two tables side by side.

just hcat the tables