ronisbr / prettytables.jl Goto Github PK
View Code? Open in Web Editor NEWPrint data in formatted tables.
License: MIT License
Print data in formatted tables.
License: MIT License
Currently the matrix format uses a slight variation of the default format, by using the box drawing characters and simply suppressing the top, bottom and middle lines of the table:
┌ ┐
│ 1 false 1.0 1 │
│ 2 true 2.0 2 │
│ 3 false 3.0 3 │
└ ┘
It would be nice if we could use actual bracket characters for the matrix backend. Unicode has dedicated characters for precisely this use case. It would look like this:
⎡ 1 false 1.0 1 ⎤
⎜ 2 true 2.0 2 ⎥
⎣ 3 false 3.0 3 ⎦
This was originally proposed in #33, but it would require more substantial changes than a mere tweak to the format, because with the extended bracket characters format the corners are not placed in a separate "row", as is the case with the current format, but rather inline with the first and last lines of actual content. Thus I'm opening a new issue to track this modification.
With very minor changes to the output code, it is possible to support rich output of Markdown.MD objects as I show in this image:
repr(MIME("text/html"), data_ij)
converts the markdown to HTML (similar for "text/plain" and "text/latex"). It makes sense to handle markdown differently because it is uniquely translatable into other common output formats.
With a couple of lines of code, it is possible to add easy support for HTML links, simple text formatting and image outputs.
This would greatly enhance the utility of the tables generated by PrettyTables. One such use case is generating tables for a static HTML page. Often it is desirable to be able to include images and links in such a table. Currently, it isn't possible (I think.)
I've submitted a similar idea to DataFrames but since there is a suggestion to move to PrettyTables for output, I thought I'd also submit the idea here.
I submitted pull request #63 with some prototype code.
There should be an option to hide vertical columns bar in text backend. Something like:
hide_column_bars = [1,3,5]
should hide the bars in columns 1, 3, and 5. Notice that we must also add option for the row number column and the row name column.
Recently, I have been having problems with precompiling Tables.jl as follows:
[ Info: Precompiling PrettyTables [08abe8d2-0d0c-5749-adfa-8a2ac140af0d]
┌ Warning: Module Tables with build ID 3769548200708 is missing from the cache.
│ This may mean Tables [bd369af6-aec1-5ad0-b16a-f7cc5008161c] does not support precompilation but is imported by a module that does.
└ @ Base loading.jl:1016
[ Info: Skipping precompilation since __precompile__(false). Importing PrettyTables [08abe8d2-0d0c-5749-adfa-8a2ac140af0d].
Starting Julia...
Is this of any cause for concern?
First of all, thanks for the awesome package!
I'm currently writing an app that writes a report at the end of the process. To achieve this, I'm constructing the message, so I can print them all at once at the end. Inside the message, I'd like to print pretty_table, so I would need to get a string returned from pretty_table
function (which currently returns nothing
).
msg = "some msg"
...
msg *= "pretty table here"
msg *= "additional msg"
println(msg)
Of course I can separate the prints, but I think it would be great to be able to get the pretty_tables
's raw string. Another use case that I can think of is putting the output string (with this pretty table in it) into a file.
I'm happy to submit a PR if you can point out the best way to make this.
I am trying to use PrettyTables as an HTML creator for Julia Table data types. For that, I need the pretty_table
as a String.
I try this, but str is empty.
using Suppressor
str = @capture_out(pretty_table(x, backend = :html))
sprint
doesn't work too because of keyword argument
sprint(pretty_table, x, backend = :html)
So the only way is to use:
io = IOBuffer()
pretty_table(io, x, backend = :html)
str = String(resize!(io.data, io.size))
Is there a function that gives me the string directly? Writing and reading from io isn't that efficient.
Branching off of #18, it would be nice if there was support for multidimensional arrays. Since I opened this can of worms I'll offer a couple ideas (some bad, some less bad).
I've been treating this as multiple slices across that last two indices of an array. This is how base Julia prints arrays. I stole this bit of code from base and adapted it for interoperability with this package.
function pretty_array(
io::IO,
A::AbstractArray{T,N},
axs::Tuple=axes(A),
dnames::Tuple=ntuple(i -> Symbol(:dim_, i), N),
backend::Symbol=:text;
kwargs...
) where {T,N}
limit::Bool = get(io, :limit, false)
if isempty(A)
return nothing
end
tailinds = tail(tail(axes(A)))
keyinds = tail(tail(axs))
nd = ndims(A)-2
for I in CartesianIndices(tailinds)
idxs = I.I
if limit
for i = 1:nd
ii = idxs[i]
ind = tailinds[i]
if length(ind) > 10
if ii == ind[firstindex(ind)+3] && all(d-> idxs[d] == first(tailinds[d]), 1:i-1)
for j=i+1:nd
szj = length(axes(A, j+2))
indj = tailinds[j]
if szj > 10 && first(indj)+2 < idxs[j] <= last(indj)-3
@goto skip
end
end
#println(io, idxs)
print(io, "...\n\n")
@goto skip
end
if ind[firstindex(ind) + 2] < ii <= ind[end - 3]
@goto skip
end
end
end
end
print(io, "[$(dnames[1]), $(dnames[2]), ")
for i in 1:(nd-1)
print(io, "$(dnames[i])[$(keys(keyinds[i])[idxs[i]])], ")
end
println(io, "$(dnames[end])[", keys(keyinds[end])[idxs[end]], "]] =")
pretty_table(
io,
view(A, axes(A,1), axes(A,2), idxs...),
keys(axs[2]);
row_names=keys(axs[1]),
backend;
kwargs...
)
print(io, idxs == map(last,tailinds) ? "" : "\n")
@label skip
end
end
This works for text but might be a bit awkward for latex and html.
It would be really cool if there was a way to nest pretty printing of tables within other pretty printed tables. This would make a multidimensional array print as a vector of alternating matrix views and slice information. For example the array produced by ones(2, 2, 2)
could look somewhat like this.
┌──────────────────────────┐
│[dim_1, dim_2, dim_3[1]] =│
├──────────────────────────┤
│ 1 2 │
│ 1 1.0 1.0 │
│ 2 1.0 1.0 │
├──────────────────────────┤
│[dim_1, dim_2, dim_3[2]] =│
├──────────────────────────┤
│ 1 2 │
│ 1 1.0 1.0 │
│ 2 1.0 1 │
└──────────────────────────┘
The nice thing about this approach is that it could help you solve issues like #12 because users can combine pretty printed arrays arbitrarily to create custom subdivisions. Also, I it should be easier to use across backends because html can arbitrarily nest tables (I think latex might be able to also do this but I'm not sure).
Thanks for this awesome package. I am trying to create a "heatmap" effect on the entries of the table. I can generate colorscales with Crayons like cs = [Crayon(i) for i in 1:10]
and map each string entry in the table to one of these colors like Dict(s .=> cs)
. However, to apply each color we need to create as many highlighters as colors and then pass them all to the table. Is there any other method to create this heatmap?
Following up on #29, we should be able to get the style and body separately. If someone wants to use the table in another HTML context they should be given separately (like in a Tuple).
Since tfs are of different types, backend can be inferred from the type.
⋮
_type_backend_dict = Dict{DataType, Symbol}(TextFormat=>:text, ... )
function pretty_table(..., tf=unicode, ...)
backend = _type_backend_dict[typeof(tf)]
⋮
Hi @ronisbr, thanks for this very useful package. I am planning to add it as a dependency in one of my packages. I was wondering if it is possible to make bold some of the column headers? Say I have:
using DataFrames
df = DataFrame(a=[1,2,3], b=[4,5,6], c=[7,8,9])
How do I pretty print the table and make b
and c
bold for example? Alternatively, a feature that would be really nice to have is a highlight of the background so that we could highlight the whole column with a background column. In this example I would highlight the column a
with some color and columns b
and c
with another.
I've been using the overwrite functionality in another package. I'd be great to get a release out with it
A common case is when a table is too wide and too long to be printed in REPL.
Currently only first rows/columns that fit the display size are printed.
It would be great if there were an option for a printout like for matrices in Base (ie. printing first and last rows/columns and dropping the ones in the middle).
Also it would be nice if, when some columns are omitted when printing, there would be an optional information what was omitted under the table (probably also truncated somehow as with 10'000 columns even listing omitted column names would swamp REPL).
The formatter ft_printf
does not check if the line is a number and can be formatted. Thus, the following example fails:
julia> data = [1; 2; 3; "teste"; 4; 5]
julia> pretty_table(data; formatter = ft_printf("%.3f",[1]))
ERROR: MethodError: no method matching isfinite(::String)
Closest candidates are:
isfinite(::BigFloat) at mpfr.jl:882
isfinite(::Missing) at missing.jl:83
isfinite(::Float16) at float.jl:548
...
Stacktrace:
[1] (::getfield(Formatting, Symbol("##13#14")))(::String) at /Users/ronan.arraes/.julia/packages/Formatting/r8m21/src/cformat.jl:18
[2] #invokelatest#1 at ./essentials.jl:742 [inlined]
[3] invokelatest at ./essentials.jl:741 [inlined]
[4] (::getfield(Formatting, Symbol("##1#4")))(::String) at /Users/ronan.arraes/.julia/packages/Formatting/r8m21/src/cformat.jl:19
[5] top-level scope at none:0
[6] eval at ./boot.jl:328 [inlined]
[7] eval at /Users/ronan.arraes/.julia/packages/Formatting/r8m21/src/Formatting.jl:1 [inlined]
[8] sprintf1(::String, ::String) at /Users/ronan.arraes/.julia/packages/Formatting/r8m21/src/cformat.jl:3
[9] (::getfield(PrettyTables, Symbol("##21#23")){Array{String,1}})(::String, ::Int64) at /Users/ronan.arraes/.julia/dev/PrettyTables/src/predefined_formatters.jl:46
[10] #_pretty_table#47(::Crayon, ::Crayon, ::Crayon, ::Crayon, ::Crayon, ::Symbol, ::Dict{Tuple{Int64,Int64},Symbol}, ::Symbol, ::Nothing, ::Nothing, ::Dict{Int64,Function}, ::Tuple{}, ::Array{Int64,1}, ::Nothing, ::Bool, ::Bool, ::Bool, ::Bool, ::Nothing, ::Bool, ::Bool, ::typeof(PrettyTables._pretty_table), ::Base.TTY, ::Array{Any,1}, ::Array{String,1}, ::PrettyTableFormat) at /Users/ronan.arraes/.julia/dev/PrettyTables/src/print.jl:556
[11] (::getfield(PrettyTables, Symbol("#kw##_pretty_table")))(::NamedTuple{(:formatter,),Tuple{Dict{Int64,Function}}}, ::typeof(PrettyTables._pretty_table), ::Base.TTY, ::Array{Any,1}, ::Array{String,1}, ::PrettyTableFormat) at ./none:0
[12] #pretty_table#36 at /Users/ronan.arraes/.julia/dev/PrettyTables/src/print.jl:257 [inlined]
[13] #pretty_table at ./none:0 [inlined]
[14] #pretty_table#40 at /Users/ronan.arraes/.julia/dev/PrettyTables/src/print.jl:263 [inlined]
[15] (::getfield(PrettyTables, Symbol("#kw##pretty_table")))(::NamedTuple{(:formatter,),Tuple{Dict{Int64,Function}}}, ::typeof(pretty_table), ::Base.TTY, ::Array{Any,1}, ::PrettyTableFormat) at ./none:0
[16] #pretty_table#39(::Base.Iterators.Pairs{Symbol,Dict{Int64,Function},Tuple{Symbol},NamedTuple{(:formatter,),Tuple{Dict{Int64,Function}}}}, ::Function, ::Array{Any,1}, ::PrettyTableFormat) at /Users/ronan.arraes/.julia/dev/PrettyTables/src/print.jl:260
[17] #pretty_table at ./none:0 [inlined] (repeats 2 times)
[18] top-level scope at none:0
I have a table that gets stuck at this line because ColumnTable
only accepts a Vector
for the column names. If ColumnTable
was defined like this...
struct ColumnTable{T,V<:AbstractVector{Symbol}}
table::T
column_names::V
size::Tuple{Int,Int}
end
...then you could still guarantee a vector like interface. What do you think?
Typically, the header of longtables is repeated after a page break. In addition, it is possible to show a message before the header (after a page break), and in the footer (before a page break). The footer message is taken care of by way of the longtable_footer
keyword argument. But it would be great to add repeated headers and pre-header messages. Here's a real-life example:
\begin{longtable}[c]{lrrrrrrrrrrrrrrr}
\hline
Name & n & p & m & S & \(\tfrac{1}{2}\|F(x)\|^2\) & \(\Delta t\) & \(\|\nabla L\|\) & \#F & \#JF & \#HF & \#c & \#Jc & \#Hc & Nfact & nBK \\
\hline
\endfirsthead
\multicolumn{16}{l}
{{\bfseries \tablename\ \thetable{} --- continued from previous page}} \\
\hline
Name & n & p & m & S & \(\tfrac{1}{2}\|F(x)\|^2\) & \(\Delta t\) & \(\|\nabla L\|\) & \#F & \#JF & \#HF & \#c & \#Jc & \#Hc & Nfact & nBK \\
\hline
\endhead
\hline
\multicolumn{16}{r}{{\bfseries Continued on next page}} \\
\hline
\endfoot
\hline
\endlastfoot
% table data ...
\hline
\end{longtable}
There, you can see the pre-header message {{\bfseries \tablename\ \thetable{} --- continued from previous page}}
. The header is repeated thanks to the ... \endfirsthead ... \endhead
.
Would that be difficult to add to the current LaTeX backend?
Thanks for a great package!
Used to output the table as a mathematical matrix.
REPL -
The borders of
unicode
, but without the horizontal lines. Center align by default if possible.
┌ ┐
│ 1 false 1.0 1 │
│ 2 true 2.0 2 │
│ 3 false 3.0 3 │
└ ┘
LaTeX -
$$ \left[
\begin{array}{ c c }
1 & 2 \\
3 & 4
\end{array} \right]
$$
pretty_table(DataFrame(A = 1:4, B = ["M", "F", "F", "M"]), backend = :html, standalone = false)
ERROR: MethodError: no method matching _pt_html(::Base.TTY, ::PrettyTables.PrintInfo{DataFrame,Array{Any,2}}; standalone=false)
Closest candidates are:
_pt_html(::Any, ::Any; tf, cell_alignment, formatter, highlighters, linebreaks, noheader, nosubheader, show_row_number) at C:\Users\yahyaaba\.julia\packages\PrettyTables\zHWjk\src\backends\html\print.jl:20 got unsupported keyword argument "standalone"
Stacktrace:
[1] kwerr(::NamedTuple{(:standalone,),Tuple{Bool}}, ::Function, ::Base.TTY, ::PrettyTables.PrintInfo{DataFrame,Array{Any,2}}) at .\error.jl:125
[2] #_pt_html at .\none:0 [inlined]
[3] #_pretty_table#61(::Symbol, ::Symbol, ::Nothing, ::Nothing, ::Base.Iterators.Pairs{Symbol,Bool,Tuple{Symbol},NamedTuple{(:standalone,),Tuple{Bool}}}, ::typeof(PrettyTables._pretty_table), ::Base.TTY, ::DataFrame, ::Array{Any,2}) at
C:\Users\yahyaaba\.julia\packages\PrettyTables\zHWjk\src\print.jl:491
[4] (::PrettyTables.var"#kw##_pretty_table")(::NamedTuple{(:backend, :standalone),Tuple{Symbol,Bool}}, ::typeof(PrettyTables._pretty_table), ::Base.TTY, ::DataFrame, ::Array{Any,2}) at .\none:0
[5] #pretty_table#58(::Base.Iterators.Pairs{Symbol,Any,Tuple{Symbol,Symbol},NamedTuple{(:backend, :standalone),Tuple{Symbol,Bool}}}, ::typeof(pretty_table),
::Base.TTY, ::DataFrame) at C:\Users\yahyaaba\.julia\packages\PrettyTables\zHWjk\src\print.jl:376
[6] (::PrettyTables.var"#kw##pretty_table")(::NamedTuple{(:backend, :standalone),Tuple{Symbol,Bool}}, ::typeof(pretty_table), ::Base.TTY, ::DataFrame) at .\none:0
[7] #pretty_table#57(::Base.Iterators.Pairs{Symbol,Any,Tuple{Symbol,Symbol},NamedTuple{(:backend, :standalone),Tuple{Symbol,Bool}}}, ::typeof(pretty_table),
::DataFrame) at C:\Users\yahyaaba\.julia\packages\PrettyTables\zHWjk\src\print.jl:348
[8] (::PrettyTables.var"#kw##pretty_table")(::NamedTuple{(:backend, :standalone),Tuple{Symbol,Bool}}, ::typeof(pretty_table), ::DataFrame) at .\none:0
[9] top-level scope at none:0
Just wanted to leave a quick note about the most recent release of Tables 0.2, which made Tables.istable
more conservative in terms of what it considers Tables.jl-compatible. The truth is that there are some objects that are valid tables, but can't be determined as such until you start iterating them (like Generators of NamedTuples, or Vector{Any} where elements are NamedTuples).
One thing you could change would be to remove this line. Just calling Tables.columns(table)
will attempt to create a table from the input, and throw its own error if the input isn't a valid table. The advantage is that Tables.columns
will treat these "nonstandard" objects as valid tables (Generators, Vector{Any}, etc.). If you'd still like to throw your own error, you can just wrap your Tables.columns
call in a try-catch.
Anyway, hope this is helpful.
Hi @ronisbr ,
I am just wondering if it is possible to setting maximum column width (max_colwidth
) with the current version? If not, I think it would be great to have one. While screen_size
option takes the maximum character of the printed table itself, this option can set the maximum character in a column. This is similar on what pandas.options
has by setting in display.max_colwidth
.
Another relevant feature, which maybe useful, is user can specify the behavior when the column exceeds max_colwidth
. With this, the user will be able to choose between crop (...
on remaining characters), or split with new line, that is split the remaining character into new line (maybe split in closest whitespace). The latter is now possible to do with manual work on adding \n
in string with linebreaks=true
.
These options are useful for particularly printing long text data in tabular form.
Thanks
Add vertical separators in LaTeX backend formats.
#33 cannot be completely rectified until then.
I wonder if there is any support or plan to support multicolumn headers. The idea would be to produce something in the vein of
┌───────────────────┬───────────────────┐
│ Header 1 │ Header 2 │
├──────────┬────────┼────────┬──────────┤
│ Col. 1 │ Col. 2 │ Col. 3 │ Col. 4 │
├──────────┼────────┼────────┼──────────┤
│ 1.000 │ false │ 1.0 │ 1.000 │
│ 2.000 │ true │ 2.0 │ 2.000 │
│ 3.000 │ false │ 3.0 │ 3.000 │
│ 4.000 │ true │ 4.0 │ 4.000 │
│ 5.000 │ false │ 5.0 │ 5.000 │
│ 6.000 │ true │ 6.0 │ 6.000 │
└──────────┴────────┴────────┴──────────┘
Thanks!
Hi,
would be nice to be able to use PrettyTables with OrderedDict (I would like to pretty print a dictionary whith the insertion order...)
install a python used to get the dataframe
pip install opendatatools
using Tables
using PyCall
using PrettyTables
using Pandas
fx = pyimport("opendatatools.fx")
cny_spot = fx.get_cny_spot_price()
@info cny_spot
cny_spot_pdf = Pandas.DataFrame(cny_spot)[[ "time", "ccyPair","askPrc", "bidPrc"]]
@info cny_spot_pdf
msg = pretty_table(String, cny_spot_pdf, [ "time", "ccyPair","askPrc", "bidPrc"], nosubheader = true)
@info msg
I get this when trying to print a Pandas.DataFrame. This code used to work fine for months. Now it is broken:
Stacktrace:
[1] error(::String) at ./error.jl:33
[2] _pretty_table_Tables(::Base.GenericIOBuffer{Array{UInt8,1}}, ::Pandas.DataFrame, ::Array{String,1}; kwargs::Base.Iterators.Pairs{Symbol,Bool,Tuple{Symbol},NamedTuple{(:nosubheader,),Tuple{Bool}}}) at /home/gsc/.julia/packages/PrettyTables/BRTPU/src/print.jl:627
[3] pretty_table(::Base.GenericIOBuffer{Array{UInt8,1}}, ::Pandas.DataFrame, ::Array{String,1}; kwargs::Base.Iterators.Pairs{Symbol,Bool,Tuple{Symbol},NamedTuple{(:nosubheader,),Tuple{Bool}}}) at /home/gsc/.julia/packages/PrettyTables/BRTPU/src/print.jl:568
[4] pretty_table(::Type{String}, ::Pandas.DataFrame, ::Array{String,1}; kwargs::Base.Iterators.Pairs{Symbol,Bool,Tuple{Symbol},NamedTuple{(:nosubheader,),Tuple{Bool}}}) at /home/gsc/.julia/packages/PrettyTables/BRTPU/src/print.jl:587
[5] currency() at /mnt/dev/home/gsc/Documents/jl_pipeline/summary/AggSum.jl:116
[6] call_module(::Module, ::String, ::Tuple{}, ::NamedTuple{(),Tuple{}}) at /home/gsc/.julia/packages/Jfire/EQ4fk/src/Jfire.jl:308
[7] macro expansion at ./util.jl:175 [inlined]
[8] Fire(::Module; time::Bool, color::Symbol, info::Bool) at /home/gsc/.julia/packages/Jfire/EQ4fk/src/Jfire.jl:21
[9] top-level scope at /mnt/dev/home/gsc/Documents/jl_pipeline/summary/AggSum.jl:258
[10] include(::Module, ::String) at ./Base.jl:377
[11] exec_options(::Base.JLOptions) at ./client.jl:288
[12] _start() at ./client.jl:484
in expression starting at /mnt/dev/home/gsc/Documents/jl_pipeline/summary/AggSum.jl:257
After updating to DataFrames 0.19.0, strings are printed surrounded by escaped quote marks \"
:
julia> df = DataFrame(:a => [1, 2], :b => ["A", "B"]);
julia> pretty_table(df)
┌───────┬────────┐
│ a │ b │
│ Int64 │ String │
├───────┼────────┤
│ 1 │ \"A\" │
│ 2 │ \"B\" │
└───────┴────────┘
For the time being, I'm able to get around this issue like this:
julia> pretty_table(df; formatter=Dict(0 => (v,i) -> v[1]))
┌───────┬────────┐
│ a │ b │
│ Int64 │ String │
├───────┼────────┤
│ 1 │ A │
│ 2 │ B │
└───────┴────────┘
Thanks for the work you've done on this library - it's really useful.
A helpful feature would be to automatically display a subset of rows and/or columns if there are too many. For example as pandas does:
In [227]: pd.DataFrame(np.random.random((1000, 1000)))
0 1 2 3 4 5 6 ... 993 994 995 996 997 998 999
0 0.662377 0.147228 0.000156 0.374437 0.735789 0.410231 0.265684 ... 0.700133 0.242414 0.994015 0.216102 0.090840 0.999337 0.842165
1 0.886247 0.286769 0.154460 0.336475 0.503869 0.032578 0.966964 ... 0.344383 0.359291 0.376371 0.508295 0.440042 0.501279 0.758484
2 0.527957 0.017837 0.494428 0.710617 0.286020 0.893393 0.218301 ... 0.207673 0.493304 0.094971 0.553760 0.756695 0.810122 0.963519
3 0.108006 0.655043 0.085983 0.726211 0.227652 0.371408 0.104541 ... 0.364350 0.728858 0.417892 0.031967 0.638570 0.951663 0.095010
4 0.729689 0.294591 0.935732 0.920085 0.681717 0.872340 0.389094 ... 0.273119 0.325299 0.201808 0.132703 0.718826 0.504016 0.662528
5 0.661268 0.329525 0.166873 0.232237 0.739869 0.034616 0.065427 ... 0.340898 0.110192 0.401961 0.777604 0.191056 0.294128 0.183806
6 0.832268 0.289802 0.150812 0.291639 0.924650 0.331622 0.773019 ... 0.725570 0.650703 0.671127 0.454935 0.694390 0.980312 0.797271
7 0.043995 0.410506 0.323817 0.718129 0.245959 0.651375 0.941751 ... 0.294927 0.480062 0.491680 0.949068 0.295438 0.909823 0.186477
8 0.615548 0.091418 0.435879 0.643807 0.377482 0.440373 0.703948 ... 0.340617 0.676066 0.843119 0.550136 0.309340 0.137899 0.012102
9 0.387807 0.136175 0.010456 0.353689 0.036754 0.452430 0.954724 ... 0.037694 0.396574 0.207781 0.003069 0.852361 0.933290 0.914244
10 0.705344 0.991054 0.616430 0.818915 0.995338 0.834266 0.182706 ... 0.750482 0.695549 0.459755 0.609368 0.254345 0.531423 0.657613
11 0.585953 0.744735 0.559609 0.309403 0.189002 0.451299 0.863537 ... 0.454540 0.092333 0.934573 0.962165 0.483714 0.644981 0.258665
12 0.290342 0.833783 0.874234 0.479235 0.481027 0.582810 0.877660 ... 0.285261 0.726311 0.507252 0.086389 0.426133 0.834218 0.855999
13 0.505773 0.774462 0.797118 0.543924 0.173187 0.151170 0.224391 ... 0.699277 0.802741 0.224662 0.886673 0.144250 0.208345 0.354224
14 0.717971 0.329965 0.667356 0.292235 0.041726 0.293648 0.115642 ... 0.687920 0.388455 0.006470 0.112481 0.987364 0.277253 0.566498
15 0.123195 0.535523 0.238964 0.597267 0.900552 0.700373 0.824251 ... 0.674168 0.557666 0.514286 0.424618 0.064353 0.190741 0.444848
16 0.593712 0.203766 0.420633 0.018746 0.928861 0.520429 0.278863 ... 0.618020 0.345239 0.316922 0.688699 0.612530 0.850708 0.736901
17 0.698404 0.628731 0.606024 0.102602 0.498215 0.485394 0.190246 ... 0.711349 0.781827 0.374240 0.908581 0.594495 0.628599 0.563909
18 0.247387 0.689242 0.787212 0.494642 0.357551 0.751359 0.369359 ... 0.008968 0.205539 0.905082 0.256709 0.781964 0.114284 0.855696
19 0.985452 0.240123 0.034268 0.922946 0.536419 0.967111 0.181938 ... 0.547363 0.376764 0.758626 0.798237 0.733275 0.711825 0.886293
20 0.535584 0.531095 0.719028 0.747534 0.359892 0.195045 0.831371 ... 0.553293 0.298446 0.787487 0.682378 0.617641 0.580587 0.834681
21 0.521069 0.912984 0.214667 0.546737 0.973207 0.600061 0.065955 ... 0.467703 0.883320 0.897581 0.477379 0.567256 0.796406 0.832179
22 0.115006 0.311789 0.524892 0.782188 0.927652 0.571370 0.886920 ... 0.908618 0.156063 0.671060 0.037652 0.061549 0.067653 0.681621
23 0.739977 0.642855 0.744133 0.123049 0.092887 0.813095 0.920146 ... 0.346283 0.138339 0.320195 0.095427 0.596392 0.886739 0.168603
24 0.374712 0.532414 0.380371 0.404624 0.380297 0.891088 0.310736 ... 0.315233 0.320222 0.236602 0.200579 0.994191 0.538467 0.953686
25 0.737192 0.588607 0.075747 0.279665 0.120362 0.221184 0.265231 ... 0.542755 0.762787 0.049258 0.924568 0.736269 0.096005 0.946525
26 0.054898 0.124825 0.474196 0.506947 0.445425 0.573363 0.585513 ... 0.971994 0.945240 0.751253 0.104149 0.937568 0.227521 0.296485
27 0.310118 0.989274 0.089343 0.073809 0.180045 0.152421 0.673879 ... 0.333157 0.575407 0.256329 0.214082 0.791568 0.550042 0.124282
28 0.737359 0.848023 0.580026 0.935866 0.019441 0.238465 0.929268 ... 0.242229 0.555528 0.291186 0.964747 0.165734 0.402035 0.123462
29 0.121833 0.201438 0.080743 0.597268 0.718605 0.636475 0.589282 ... 0.642448 0.396119 0.234419 0.191797 0.244088 0.239554 0.270473
.. ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
970 0.960581 0.769818 0.224361 0.732218 0.840654 0.690809 0.266942 ... 0.531059 0.069592 0.450537 0.542496 0.897009 0.506210 0.642513
971 0.259726 0.566016 0.981401 0.440334 0.340194 0.730820 0.737997 ... 0.226347 0.142284 0.482753 0.601454 0.905018 0.061511 0.612320
972 0.799145 0.991555 0.690505 0.715953 0.800496 0.208339 0.697829 ... 0.525792 0.844460 0.062547 0.568521 0.933060 0.343736 0.641958
973 0.463105 0.190884 0.482059 0.576830 0.748321 0.581880 0.107534 ... 0.508975 0.258424 0.017235 0.761781 0.093348 0.114263 0.839027
974 0.752325 0.879876 0.793081 0.915137 0.227987 0.797046 0.706861 ... 0.203348 0.072367 0.015860 0.911643 0.806820 0.245869 0.101746
975 0.926122 0.091514 0.398097 0.863483 0.739247 0.105190 0.683835 ... 0.551782 0.446727 0.482680 0.945226 0.209836 0.410465 0.964114
976 0.675757 0.304480 0.450098 0.916315 0.267746 0.756051 0.594941 ... 0.172209 0.810840 0.623759 0.875499 0.575256 0.226666 0.491496
977 0.668797 0.773131 0.991445 0.132439 0.019331 0.715174 0.822106 ... 0.376085 0.011035 0.212870 0.257827 0.795227 0.159010 0.647967
978 0.588282 0.804102 0.209700 0.572460 0.555175 0.392894 0.447815 ... 0.873659 0.789392 0.775508 0.826018 0.612214 0.772600 0.373065
979 0.321075 0.862837 0.438074 0.667402 0.825376 0.779966 0.691062 ... 0.836253 0.387061 0.405808 0.649105 0.462068 0.262024 0.712526
980 0.453232 0.811904 0.429339 0.813175 0.123825 0.899411 0.797631 ... 0.939058 0.688701 0.940761 0.555159 0.488190 0.490079 0.228867
981 0.778713 0.335743 0.228914 0.757888 0.197474 0.555572 0.271340 ... 0.680641 0.288119 0.724131 0.366246 0.244317 0.002680 0.369249
982 0.212745 0.911184 0.899036 0.692147 0.809090 0.601847 0.967257 ... 0.561234 0.862002 0.385914 0.635437 0.990514 0.653080 0.777237
983 0.291510 0.029607 0.315777 0.652494 0.194797 0.298109 0.436917 ... 0.275267 0.563190 0.928654 0.129364 0.390446 0.561311 0.400901
984 0.992107 0.046735 0.756767 0.233308 0.023014 0.933423 0.842957 ... 0.069899 0.378425 0.130341 0.331038 0.345648 0.906547 0.543608
985 0.530613 0.485466 0.946213 0.376432 0.823469 0.690564 0.890659 ... 0.669394 0.379153 0.878831 0.678995 0.687055 0.379061 0.145143
986 0.972634 0.942601 0.082842 0.209644 0.662084 0.774273 0.327364 ... 0.879357 0.117271 0.725847 0.346310 0.571028 0.824266 0.092810
987 0.645181 0.789499 0.487647 0.074670 0.172397 0.329517 0.951295 ... 0.750394 0.494127 0.746699 0.628286 0.983010 0.642206 0.663819
988 0.659353 0.220577 0.882972 0.723706 0.301519 0.763145 0.309886 ... 0.702753 0.213555 0.224452 0.721929 0.598715 0.704451 0.084021
989 0.702995 0.801176 0.518151 0.015434 0.376514 0.772242 0.014960 ... 0.357517 0.406269 0.188028 0.911998 0.107809 0.621717 0.850320
990 0.583927 0.972048 0.949423 0.890679 0.823851 0.125045 0.088132 ... 0.408108 0.042695 0.742867 0.954959 0.939769 0.366634 0.709486
991 0.121613 0.813868 0.595742 0.876439 0.075714 0.803625 0.780191 ... 0.154492 0.665987 0.281068 0.119310 0.441230 0.439666 0.402334
992 0.843894 0.160468 0.328034 0.163152 0.009397 0.362727 0.996105 ... 0.390673 0.885662 0.742446 0.150888 0.493537 0.419742 0.912172
993 0.326680 0.943335 0.873457 0.863872 0.638356 0.599924 0.466651 ... 0.078415 0.470194 0.095438 0.176634 0.171471 0.392283 0.215391
994 0.914795 0.115723 0.556118 0.821460 0.737229 0.618206 0.583068 ... 0.339856 0.608108 0.631514 0.340248 0.899115 0.137592 0.950671
995 0.489507 0.859164 0.682648 0.108186 0.131638 0.239109 0.940722 ... 0.943679 0.474852 0.499830 0.958643 0.600407 0.612542 0.751645
996 0.284132 0.109273 0.729429 0.073182 0.339664 0.998147 0.878563 ... 0.451112 0.446906 0.357696 0.763285 0.919360 0.002211 0.161077
997 0.110467 0.621064 0.070086 0.506337 0.791058 0.895068 0.152964 ... 0.436509 0.854434 0.309656 0.116588 0.420178 0.685615 0.898698
998 0.973428 0.480761 0.196547 0.039439 0.947259 0.192339 0.949248 ... 0.597220 0.157047 0.770161 0.337967 0.951522 0.078311 0.287462
999 0.681836 0.022469 0.017463 0.072766 0.131688 0.334997 0.467333 ... 0.519279 0.519814 0.774350 0.584059 0.947693 0.142431 0.526454
[1000 rows x 1000 columns]
The pretty_table
method could for example take max_rows
and max_cols
arguments.
Here is a bug report for using prettytables with Tables.jl
julia> using Tables, PrettyTables
julia> t = (a = rand(10), b = rand(10))
julia> Tables.istable(t) #true, so things should work
julia> prettyprint(t)
ERROR: UndefVarError: prettyprint not defined
Stacktrace:
[1] top-level scope at REPL[31]:1
julia> pretty_table(t)
ERROR: MethodError: no method matching size(::NamedTuple{(:a, :b),Tuple{Array{Float64,1},Array{Float64,1}}})
Closest candidates are:
size(::BitArray{1}) at bitarray.jl:77
size(::BitArray{1}, ::Integer) at bitarray.jl:81
size(::Core.Compiler.StmtRange) at show.jl:1585
...
Stacktrace:
[1] #_pretty_table#61(::Symbol, ::Symbol, ::Nothing, ::Nothing, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(PrettyTables._pretty_table), ::Base.TTY, ::NamedTuple{(:a, :b),Tuple{Array{Float64,1},Array{Float64,1}}}, ::Array{Any,2}) at /home/peterwd/.julia/packages/PrettyTables/zHWjk/src/print.jl:395
[2] _pretty_table(::Base.TTY, ::NamedTuple{(:a, :b),Tuple{Array{Float64,1},Array{Float64,1}}}, ::Array{Any,2}) at /home/peterwd/.julia/packages/PrettyTables/zHWjk/src/print.jl:395
[3] #pretty_table#58(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(pretty_table), ::Base.TTY, ::NamedTuple{(:a, :b),Tuple{Array{Float64,1},Array{Float64,1}}}) at /home/peterwd/.julia/packages/PrettyTables/zHWjk/src/print.jl:376
[4] pretty_table(::Base.TTY, ::NamedTuple{(:a, :b),Tuple{Array{Float64,1},Array{Float64,1}}}) at /home/peterwd/.julia/packages/PrettyTables/zHWjk/src/print.jl:355
[5] #pretty_table#57(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(pretty_table), ::NamedTuple{(:a, :b),Tuple{Array{Float64,1},Array{Float64,1}}}) at /home/peterwd/.julia/packages/PrettyTables/zHWjk/src/print.jl:348
[6] pretty_table(::NamedTuple{(:a, :b),Tuple{Array{Float64,1},Array{Float64,1}}}) at /home/peterwd/.julia/packages/PrettyTables/zHWjk/src/print.jl:348
[7] top-level scope at REPL[32]:1
I like this package and its level of customizations.
A feature I miss is the possibility to remove the line between header and data the same way the top and bottom lines can be removed.
Thanks.
The header strings must be escapes, otherwise we can break the format by using escape sequences:
julia> data = Any[1 false 1.0 0x01 ;
2 true 2.0 0x02 ;
3 false 3.0 0x03 ;
4 true 4.0 0x04 ;
5 false 5.0 0x05 ;
6 true 6.0 0x06 ;];
julia> pretty_table(data, ["1" "2\n" "3" "4"])
┌───┬───────┬─────┬───┐
│ 1 │ 2
│ 3 │ 4 │
├───┼───────┼─────┼───┤
│ 1 │ false │ 1.0 │ 1 │
│ 2 │ true │ 2.0 │ 2 │
│ 3 │ false │ 3.0 │ 3 │
│ 4 │ true │ 4.0 │ 4 │
│ 5 │ false │ 5.0 │ 5 │
│ 6 │ true │ 6.0 │ 6 │
└───┴───────┴─────┴───┘
Thanks for a very nice package! I've tried to use this with StructArrays but ran into the following limitation. A StructArray
is a table but also an AbstractVector
, and the same holds for TypedTables, and even Vector{NamedTuple}
(which again is a table in the Tables.istable
sense). The issue is that pretty_table
uses the AbstractVector
fallback, giving the following:
julia> using PrettyTables, StructArrays
julia> pretty_table(StructArray(a=1:2, b=1:2))
┌────────────────┐
│ Col. 1 │
├────────────────┤
│ (a = 1, b = 1) │
│ (a = 2, b = 2) │
└────────────────┘
Would it be possible to check for Tables.istable
before going for the AbstractVector
fallback?
First of all: awesome package! The less often I have to leave my terminal, the better.
A reasonable way to represent a table is Dict{ID, Dict{Keys, Values}}
. I hacked something together for my use case, but it might be nice for PrettyTables
to support this natively.
I would like to use PrettyTables to format the display of Tables-like data in Pluto and IJulia notebooks.
The Problem with Pluto-notebooks and PrettyTables is that Pluto only displays the resulting object of a cell, not anything that was printed with print
. This is on purpose and makes sense to me. And it works nicely for most custom types like Plots or DataFrames, since they can decide for each frontend (REPL or Pluto and IJulia) how they want to display them self.
It works not as nicely with PrettyTables since it either prints to STDOUT or returns a string. The former is not shown in Pluto and the latter only shows the content of the string, it is not interpreted.
These Problems would be solved nicely if PrettyTables.jl could extend its API by something like the Plots-API where something like a prettytable
-Method would return a custom type that stores the data and the formatting.
Support for the correct display on the different frontends could then be added by extending the show
-Method for the according MIME types.
It seems the support is halfway there, but not quite? In _pretty_table_Tables
, we find the following lines:
data = Tables.matrix(table)
if sch == nothing
However, if the schema is nothing
(the default), Tables.matrix
won't work, as the second thing it does is to access sch.types
(which does not exist).
I guess Tables.matrix
can't be used at all in this case (unless that itself is updated to use Any
as column types when there is no schema, or something)…
As for the colum names: The body of the if sch == nothing
clause constructs new column names, if they aren't supplied directly as an argument – but there's no need to do that, as columnnames
is a required part of the Tables.jl
interface (as opposed to schema
). Slightly easier to access for columnaccess
tables (as for rowaccess
tables, you'd have to extract the first row to get the column names), but doable either way.
An alternative is to require schema
, but in that case there's no need for the current code that tries to handle the no-schema condition.
Although the slowness is acknowledged in the documentation, it is extreme for some format strings. I have found this pattern to be a good alternative:
using Formatting
ff = generate_formatter("%.3g")
ft_ff = Dict{Int,Function}(0 => (v,i) -> ff(v))
pretty_table(table, header, formatter=ft_ff)
If dependence on Formatting.jl is undesirable, it would still be helpful to mention this in the documentation. (The above format takes several seconds for 100 numbers with wide dynamic range using ft_printf
, vs several millisec with Formatting.)
It is missing a space when printing tables with the row number columns and sub-headers:
julia> A = rand(2,2)
2×2 Array{Float64,2}:
0.791187 0.814946
0.638271 0.809555
julia> pretty_table(A, [1 2; 3 4; 5 6]; show_row_number = true)
┌─────┬────────────────────┬───────────────────┐
│ Row │ 1 │ 2 │
│ │ 3 │ 4 │
│ │ 5 │ 6 │
├─────┼────────────────────┼───────────────────┤
│ 1 │ 0.7911872142374308 │ 0.814945597280401 │
│ 2 │ 0.6382713446539856 │ 0.809554674993012 │
└─────┴────────────────────┴───────────────────┘
``
That would pretty much solve all the problems related to printing tables in Julia 👍
I tried passing headers to pretty_table() and it shows:
ERROR: LoadError: MethodError: no method matching pretty_table(::DataFrames.DataFrame, ::Array{String,}; formatter=Dict(0=>##4#9()))
Closest candidates are:
pretty_table(!Matched::Union{AbstractArray{T1,1}, AbstractArray{T1,2}}, ::Union{AbstractArray{T2,1},AbstractArray{T2,2}}) where {T1, T2} at /home/sgao/.julia/packages/PrettyTables/KRUFv/src/print.jl:268got unsupported keyword argument "formatter"
pretty_table(!Matched::Union{AbstractArray{T1,1}, AbstractArray{T1,2}}, ::Union{AbstractArray{T2,1},AbstractArray{T2,2}}, !Matched::PrettyTables.PrettyTableFormat; kwargs...) where {T1, T2} at /home/sga/.julia/packages/PrettyTables/KRUFv/src/print.jl:268
pretty_table(!Matched::IO, ::Union{AbstractArray{T,1}, AbstractArray{T,2}}) where T at /home/sgao/.jlia/packages/PrettyTables/KRUFv/src/print.jl:282 got unsupported keyword argument "formatter"
...
Stacktrace:
[1] pnl_ana(::String, ::String, ::String, ::String, ::String) at /home/sgao/Documents/pnl_ana/pnl_anayser.jl:72
[2] main() at /home/sgao/Documents/pnl_ana/paa.jl:16
[3] top-level scope at none:0
[4] include at ./boot.jl:326 [inlined]
[5] include_relative(::Module, ::String) at ./loading.jl:1038
[6] include(::Module, ::String) at ./sysimg.jl:29
[7] exec_options(::Base.JLOptions) at ./client.jl:267
[8] _start() at ./client.jl:436
in expression starting at /home/sgao/Documents/pnl_ana/paa.jl:20
I just want to disable the type in headers, is there a simple way?
Is there a way to not wrap the table header in \textbf{}
in the LaTeX backend? When we want to use math in the header, some items are bold and some not because \textbf{\(f\)}
doesn't display "f" in bold math.
Example from the documentation:
julia> header = ["\\(t\\)" "\\(a\\)" "Velocity" "Distance";
"[s]" "[m/s\$^2\$]" "[m/s]" "[m]"];
julia> pretty_table(data, header, backend = :latex)
what about supplying a convenience function for printing matrices (without headers and borders)
pretty_matrix(x) = pretty_table(x,fill("",size(x,2)),borderless)
I bet some users would like it.
Btw. the manual could mention that formatter=ft_print(fmt)
does not require fmt to be hardcoded. That's a nice feature (compared to, say, @sprintf)
Hi and thanks for your package!
Is it possible to export a table to pdf/png etc?
Add title option for tables, especially in HTML and Latex.
MWE:
using DataFrames
using Measurements
using LaTeXStrings
using PrettyTables
##
data = DataFrame(Dict(
L"A" => [12341],
L"V" => [4.1234],
L"v" => [3.231],
L"R_\text{ne}" => [2.01234± 0.1234],
))
pretty_table(data, backend=:latex)
##
ERROR: UndefVarError: isoverlong not defined
Stacktrace:
[1] _str_latex_escaped(::Base.GenericIOBuffer{Array{UInt8,1}}, ::String, ::String) at /Users/christ/.julia/packages/PrettyTables/4nnoz/src/backends/latex/private.jl:77
[2] #sprint#340(::Nothing, ::Int64, ::Function, ::Function, ::String, ::Vararg{Any,N} where N) at ./strings/io.jl:101
[3] #sprint at ./none:0 [inlined]
[4] _str_latex_escaped at /Users/christ/.julia/packages/PrettyTables/4nnoz/src/backends/latex/private.jl:92 [inlined] (repeats 2 times)
[5] #_pt_latex#140(::LatexTableFormat, ::Dict{Tuple{Int64,Int64},Symbol}, ::Dict{Any,Any}, ::Tuple{}, ::Array{Int64,1}, ::Nothing, ::Bool, ::Bool, ::Bool, ::Bool, ::Symbol, ::Array{Int64,1}, ::typeof(PrettyTables._pt_latex), ::Base.TTY, ::PrettyTables.PrintInfo{Array{Measurement{Float64},2},Array{Any,2}}) at /Users/christ/.julia/packages/PrettyTables/4nnoz/src/backends/latex/print.jl:89
[6] _pt_latex at /Users/christ/.julia/packages/PrettyTables/4nnoz/src/backends/latex/print.jl:24 [inlined]
[7] #_pretty_table#78(::Symbol, ::Symbol, ::Nothing, ::Nothing, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function, ::Base.TTY, ::Array{Measurement{Float64},2}, ::Array{Any,2}) at /Users/christ/.julia/packages/PrettyTables/4nnoz/src/print.jl:586
[8] (::getfield(PrettyTables, Symbol("#kw##_pretty_table")))(::NamedTuple{(:backend,),Tuple{Symbol}}, ::typeof(PrettyTables._pretty_table), ::Base.TTY, ::Array{Measurement{Float64},2}, ::Array{Any,2}) at ./none:0
[9] #pretty_table#75(::Base.Iterators.Pairs{Symbol,Symbol,Tuple{Symbol},NamedTuple{(:backend,),Tuple{Symbol}}}, ::Function, ::Base.TTY, ::DataFrame) at /Users/christ/.julia/packages/PrettyTables/4nnoz/src/print.jl:469
[10] (::getfield(PrettyTables, Symbol("#kw##pretty_table")))(::NamedTuple{(:backend,),Tuple{Symbol}}, ::typeof(pretty_table), ::Base.TTY, ::DataFrame) at ./none:0
[11] #pretty_table#74(::Base.Iterators.Pairs{Symbol,Symbol,Tuple{Symbol},NamedTuple{(:backend,),Tuple{Symbol}}}, ::Function, ::DataFrame) at /Users/christ/.julia/packages/PrettyTables/4nnoz/src/print.jl:444
[12] (::getfield(PrettyTables, Symbol("#kw##pretty_table")))(::NamedTuple{(:backend,),Tuple{Symbol}}, ::typeof(pretty_table), ::DataFrame) at ./none:0
[13] top-level scope at none:0
When printing a table with the row column and without the header, we should not take into account the size of Row
to align the row column:
julia> v = 0:1:6
0:1:6
julia> pretty_table(v;noheader = true, show_row_number = true)
┌─────┬───┐
│ 1 │ 0 │
│ 2 │ 1 │
│ 3 │ 2 │
│ 4 │ 3 │
│ 5 │ 4 │
│ 6 │ 5 │
│ 7 │ 6 │
└─────┴───┘
Hello,
Thanks for your package, very useful! I was wondering whether it'd be possible to add a tilte=...
kwarg to pretty_table
to have the table displayed with a title; that's convenient when displaying multiple tables in a sequence for different combine/groupby
.
Thanks!
If a column of strings contains "
characters then they are printed like:
func(\"temp\")
I'd like to be able to print the table as in print
, like:
func("temp")
I typically use PrettyTables for viewing "publication" results (not debugging Julia strings) so I think print
should be the default format for strings. (Love this package, BTW.)
Hi, thanks for the great package. Is there an option to print all rows in a very long table?
Presently the column char in TextFormat plays the role of column separator and that of the side borders. Introduce right_border and left_border for borders, and column handles column.
Similarly for row
#33 cannot be completely implemented until then
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.