Skip to content

Commit

Permalink
Merge pull request #244 from KristofferC/kc/tables_interface
Browse files Browse the repository at this point in the history
Use the Tables interface
  • Loading branch information
tpapp authored Aug 31, 2020
2 parents d1903ec + 571c8ef commit 2ccd5c1
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 57 deletions.
2 changes: 2 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"

[compat]
ArgCheck = "^1, 2.0"
Expand All @@ -20,6 +21,7 @@ DocStringExtensions = "^0.8"
MacroTools = "^0.5"
Parameters = "^0.12"
Requires = "0.5, 1.0"
Tables = "1"
julia = "1"

[extras]
Expand Down
2 changes: 1 addition & 1 deletion docs/Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ uuid = "90014a1f-27ba-587c-ab20-58faa44d9150"
version = "0.10.0"

[[PGFPlotsX]]
deps = ["ArgCheck", "DataStructures", "Dates", "DefaultApplication", "DocStringExtensions", "MacroTools", "Parameters", "Requires"]
deps = ["ArgCheck", "DataStructures", "Dates", "DefaultApplication", "DocStringExtensions", "MacroTools", "Parameters", "Requires", "Tables"]
path = ".."
uuid = "8314cec4-20b6-5062-9cdb-752b83310925"
version = "1.2.9"
Expand Down
4 changes: 3 additions & 1 deletion docs/src/man/data.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ table[row sep={\\}, x={Dof}, y={Err}]
}
```

If you load the DataFrames package, you can also create tables from data frames, see the examples in [Julia types](@ref).
You can give a type that supports the [`Tables.jl`](https://juliadata.github.io/Tables.jl/stable/) as the second
argument to `Table` and the data and column names will be inferred.
For example, if you load the DataFrames package, you can create tables from data frames, see the examples in [Julia types](@ref).

!!! note

Expand Down
1 change: 1 addition & 0 deletions src/PGFPlotsX.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ using DocStringExtensions: SIGNATURES, TYPEDEF
using MacroTools: prewalk, @capture
using Parameters: @unpack
using Requires: @require
using Tables: Tables

export TikzDocument, TikzPicture
export Axis, SemiLogXAxis, SemiLogYAxis, LogLogAxis, PolarAxis, SmithChart, GroupPlot
Expand Down
61 changes: 29 additions & 32 deletions src/axiselements.jl
Original file line number Diff line number Diff line change
Expand Up @@ -342,12 +342,6 @@ struct TableData
end
end

function TableData(data::AbstractMatrix, colnames, scanlines, rowsep = ROWSEP)
TableData(data,
colnames nothing ? colnames : collect(string(c) for c in colnames),
expand_scanlines(scanlines, size(data, 1)), rowsep)
end

function print_tex(io::IO, tabledata::TableData)
@unpack data, colnames, scanlines, rowsep = tabledata
_colsep() = print(io, " ")
Expand All @@ -371,6 +365,19 @@ function print_tex(io::IO, tabledata::TableData)
end
end


"""
$SIGNATURES
`data` provided directly as a matrix.
"""
function TableData(data::AbstractMatrix;
colnames = nothing, scanlines = 0, rowsep = ROWSEP)
TableData(data,
colnames nothing ? colnames : collect(string(c) for c in colnames),
expand_scanlines(scanlines, size(data, 1)), rowsep)
end

"""
$SIGNATURES
Expand All @@ -381,19 +388,7 @@ arguments.
"""
TableData(columns::Vector{<: AbstractVector}, colnames = nothing, scanlines = 0;
rowsep::Bool = ROWSEP) =
TableData(hcat(columns...), nothing, 0, rowsep)

TableData(itr; kwargs...) = TableData(collect(itr); kwargs...) # fallback

"""
$SIGNATURES
`data` provided directly as a matrix.
"""
function TableData(data::AbstractMatrix;
colnames = nothing, scanlines = 0, rowsep = ROWSEP)
TableData(data, colnames, scanlines, rowsep)
end
TableData(reduce(hcat, columns); colnames=nothing, scanlines=0, rowsep=rowsep)

"""
$SIGNATURES
Expand All @@ -403,15 +398,22 @@ Symbols or strings are accepted as column names.
"""
function TableData(name_column_pairs::Vector{<: Pair};
scanlines = 0, rowsep::Bool = ROWSEP)
TableData(hcat(last.(name_column_pairs)...), first.(name_column_pairs),
scanlines, rowsep)
TableData(reduce(hcat, last.(name_column_pairs)); colnames=first.(name_column_pairs),
scanlines=scanlines, rowsep=rowsep)
end

TableData(rest::AbstractVector...; kwargs...) = TableData(collect(rest); kwargs...)

TableData(name_column_pairs::Pair...; kwargs...) =
TableData(collect(name_column_pairs); kwargs...)

function TableData(x::AbstractVector, y::AbstractVector, z::AbstractMatrix; kwargs...)
colnames = ["x", "y", "z"]
columns = reduce(hcat, matrix_xyz(x, y, z))
return TableData(columns; colnames=colnames, scanlines=length(x), kwargs...)
end


"""
$SIGNATURES
Expand All @@ -420,22 +422,17 @@ Use the keyword arguments as columns.
Note that this precludes the possibily of providing other keywords; see the
other constructors.
"""
TableData(; named_columns...) = TableData(Pair(nc...) for nc in named_columns)
TableData(; named_columns...) = TableData(collect(Pair(nc...) for nc in named_columns))

TableData(::AbstractVector; kwargs...) =
throw(ArgumentError("Could not determine whether columns are named from the element type."))

function TableData(x::AbstractVector, y::AbstractVector, z::AbstractMatrix;
meta::Union{Nothing, AbstractMatrix} = nothing,
rowsep::Bool = ROWSEP)
colnames = ["x", "y", "z"]
columns = hcat(matrix_xyz(x, y, z)...)
if meta nothing
@argcheck size(z) == size(meta) "Incompatible sizes."
push!(colnames, "meta")
columns = hcat(columns, vec(meta))
function TableData(table; kwargs...)
if !Tables.istable(table)
error("`$(typeof(table))` does not support the Table interface")
end
TableData(columns, colnames, length(x), rowsep)
colnames = string.(Tables.columnnames(Tables.columns(table)))
TableData(Tables.matrix(table); colnames=colnames, kwargs...)
end

struct Table <: OptionType
Expand Down
19 changes: 4 additions & 15 deletions src/requires.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,8 @@ function __init__()
end
end

@require DataFrames="a93c6f00-e57d-5684-b7b6-d8193f3e46c0" begin
"""
$SIGNATURES
Construct table data from a `DataFrame`.
"""
PGFPlotsX.TableData(df::DataFrames.DataFrame; rowsep = ROWSEP) =
TableData(hcat(DataFrames.eachcol(df, false)...), string.(names(df)), 0, rowsep)
end

@require Contour="d38c429a-6771-53c6-b99e-75d170b6e991" begin
function PGFPlotsX.TableData(c::Contour.ContourCollection; rowsep = ROWSEP)
function PGFPlotsX.TableData(c::Contour.ContourCollection; kwargs...)
colx = Any[]
coly = Any[]
colz = Any[]
Expand All @@ -83,15 +73,14 @@ function __init__()
push!(ns, n)
end
end
TableData(hcat(colx, coly, colz), ["x", "y", "z"], cumsum(ns), rowsep)
TableData(hcat(colx, coly, colz); colnames=["x", "y", "z"], scanlines=cumsum(ns), kwargs...)
end
end

@require StatsBase="2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" begin
function PGFPlotsX.TableData(h::StatsBase.Histogram{T, 1};
kwargs...) where T
PGFPlotsX.TableData(hcat(h.edges[1], vcat(h.weights, 0)),
nothing, 0; kwargs...)
PGFPlotsX.TableData(hcat(h.edges[1], vcat(h.weights, 0)); kwargs...)
end

function PGFPlotsX.TableData(histogram::StatsBase.Histogram{T, 2};
Expand All @@ -103,7 +92,7 @@ function __init__()

function PGFPlotsX.TableData(e::StatsBase.ECDF; n = 100, kwargs...)
x = range(extrema(e)...; length = n)
PGFPlotsX.TableData(hcat(x, map(e, x)), nothing, 0; kwargs...)
PGFPlotsX.TableData(hcat(x, map(e, x)); kwargs...)
end

function PGFPlotsX.Coordinates(histogram::StatsBase.Histogram{T, 2}) where T
Expand Down
12 changes: 6 additions & 6 deletions test/test_elements.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ end

@testset "tables" begin
# compare results to these using ≅, defined above
table_named_noopt = Table(hcat(1:10, 11:20), ["a", "b"], Int[])
table_unnamed_noopt = Table(hcat(1:10, 11:20), nothing, Int[])
table_named_noopt = Table(hcat(1:10, 11:20); colnames=["a", "b"], scanlines=Int[])
table_unnamed_noopt = Table(hcat(1:10, 11:20); colnames=nothing, scanlines=Int[])
opt = @pgf { meaningless = "option" }
table_named_opt = Table(opt, hcat(1:10, 11:20), ["a", "b"], Int[])
table_named_opt = Table(opt, hcat(1:10, 11:20); colnames=["a", "b"], scanlines=Int[])

# named columns, without options
@test Table(:a => 1:10, :b => 11:20) table_named_noopt
Expand All @@ -100,13 +100,13 @@ end
# matrix and edges
let x = randn(10), y = randn(5), z = cos.(x .+ y')
@test Table(x, y, z) Table(PGFPlotsX.Options(),
hcat(PGFPlotsX.matrix_xyz(x, y, z)...),
["x", "y", "z"], 10)
hcat(PGFPlotsX.matrix_xyz(x, y, z)...);
colnames=["x", "y", "z"], scanlines=10)
end

# dataframe
@test Table(DataFrame(a = 1:5, b = 6:10))
Table(PGFPlotsX.Options(), hcat(1:5, 6:10), ["a", "b"], 0)
Table(PGFPlotsX.Options(), hcat(1:5, 6:10), colnames=["a", "b"], scanlines=0)

# can't determine if it is named or unnamed
@test_throws ArgumentError Table([1:10, :a => 11:20])
Expand Down
4 changes: 2 additions & 2 deletions test/test_options.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ end
end

@testset "pgf empty" begin
@test squashed_repr_tex(@pgf Plot({}, Table([], []))) ==
"\\addplot[]\ntable[row sep={\\\\}]\n{\n\\\\\n}\n;" # note []
@test squashed_repr_tex(@pgf Plot({}, Table("x" => [1,2,3]))) ==
"\\addplot[]\ntable[row sep={\\\\}]\n{\nx \\\\\n1 \\\\\n2 \\\\\n3 \\\\\n}\n;" # note []
end

@testset "options push! and append!" begin
Expand Down

0 comments on commit 2ccd5c1

Please sign in to comment.