-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LaTeX Property Trees #69
Comments
From @mykelk: One thing that I was thinking of doing was allowing varargs and then converting those key-value pairs. I turns out that Julia's version of varargs even supports non-assignments, like "black" when plotting. |
The problem with varargs is that they don't support keys containing multiple words. Of course a convention could be used so that perhaps an underline is converted to a space, however "nested" options become problematic. Regarding property trees, here is an example I tried: stringify(io::IO, s) = print(io::IO, s)
function stringify(io::IO, opts::Vector)
for opt in opts
stringify(io, opt)
println(io, ",")
end
end
function stringify(io::IO, p::Pair)
print(io, first(p), " = {")
stringify(io, last(p))
print(io, "}")
end Example: stringify(STDOUT, "legend style" => ["at" => (0.5,-0.15),
"anchor" => "north",
"legend columns" => -1]
legend style = {at = {(0.5, -0.15)},
anchor = {north},
legend columns = {-1},
}
stringify(STDOUT, "symbolic x coords" => ["excellent", "good", "neutral"])
symbolic x coords = {excellent,
good,
neutral,
}
etc |
I like this idea. I'm interested in knowing @tawheeler's thoughts. |
My previous suggestion was not so good because it makes it hard to change properties after the For example: immutable Axis
options::Dict
end
Axis(args::Vararg{Union{String, Pair{String, T} where T}}) = Axis(dictify(args))
Base.getindex(a::Axis, s::String) = a.options[s]
Base.setindex!(a::Axis, s::String, v) = a.options[s] = v
Base.delete!(a::Axis, s::String) = delete!(a.options, s)
function dictify(args)
d = Dict{String, Any}()
for arg in args
accum_opt!(d, arg)
end
return d
end
accum_opt!(d::Dict, opt::String) = d[opt] = nothing
accum_opt!(d::Dict, opt::Pair) = d[first(opt)] = valuify(last(opt))
valuify(x) = x
valuify(opts::Vector) = dictify(opts)
function stringify(io::IO, d::Dict)
for (k, v) in d
print(io, k)
if v != nothing
print(io, " = {")
stringify(io, v)
print(io, "}")
end
print(io, ", ")
end
end
stringify(io::IO, s) = print(io::IO, s) Usage: # Creating axis
a = Axis("blue",
"xlabel" => "x",
"legend style" => ["at" => (0.5,-0.15),
"anchor" => "north",
"legend columns" => -1]
)
# getindex
a["xlabel"]
# Can nest
a["legend style"]["at"]
# setindex!
a["legend style"]["anchor"] = "south"
# Make it into an option string
stringify(STDOUT, a.options)
# prints:
legend style = {anchor = {south}, at = {(0.5, -0.15)}, legend columns = {-1}, }, blue, xlabel = {x}, This also makes it easy to merge in new options, create themes etc. |
I like the Dict idea much more than the original string concept. Using native julia types would also be more natural to package users. |
Some other thoughts. It is quite unfortunate that there is no short form I tinkered a bit with creating my own, more direct pgfplots syntax package this weekend and implemented some of the figures given in the PGFPlot manual. http://nbviewer.jupyter.org/github/KristofferC/PGFPlotsXExamples/blob/master/examples/Chapter3.ipynb |
Oh, your notebook examples are quite nice. It is definitely a more direct translation. Maybe a direct translation is good, but perhaps with the existing PGFPlots.jl API wrapping it? In other words, can we wrap what you have so that the PGFPlots.jl notebook runs as is? There is some tricky stuff with colormaps and the handling of images. |
I just noticed that options are order dependent which means that one needs an |
I am really liking how this looks. |
I found some macro code that originally was intended for easier syntax when writing JSON which I tweaked a bit. With that it is possible to write things like: @pgf {
"blue",
"xlabel" = "x",
"ylabel" = "y",
"axis background/.style" = {
"shade",
"top color" = "gray",
"bottom color" = "white"
}
} and get: julia> d["xlabel"]
"x"
julia> d["axis background/.style"]["top color"]
"gray" This syntax is quite similar to the PGFPlots syntax. You can also leave out the string quotations from the keys as long as they don't contain spaces or special characters. It could be possible to have a convention to use The macro code can be found at https://gist.github.com/KristofferC/5e7f40eecb605c72251a109d7a6122ec |
I'd like to avoid the unicode. I like what you suggest @KristofferC. I wonder... is there a huge advantage of this for the user of PGFPlots over just putting all those options into one set of quotes as done right now with the |
1 similar comment
I'd like to avoid the unicode. I like what you suggest @KristofferC. I wonder... is there a huge advantage of this for the user of PGFPlots over just putting all those options into one set of quotes as done right now with the |
I just spoke with @tawheeler --- what if we have PGFPlotsX.jl (or something like that) that supports the direct pgfplots generation. Then, we can refactor PGFPlots.jl to use PGFPlotsX.jl as the backend. That way, we don't have to break anyone's code, preserve the ease of use with PGFPlots.jl, preserve the Plots.jl interface, etc. |
It should be possible to create a macro that directly supports PGFPlots syntax, spaces and all. |
I definitely think so. A few reasons:
I am sceptic because it still has to be valid Julia syntax which is what macros work on. julia> :(foo bar = 3)
ERROR: syntax: missing comma or ) in argument list |
Ah, I think you might be right on the spaces issue. I think you make a convincing argument for this. I'm a fan. |
I see, it has to support the Expr syntax so that Julia can build the AST. |
I made the macro a bit better so you can just annotate a whole chain of functions and the macro will traverse through all the arguments and replace everything with I must say that I like this a lot. |
This is beautiful! |
This is very nice! |
Not sure if you guys care but with exception of the image stuff here I think I am almost at feature parity now https://github.com/KristofferC/PGFPlotsXExamples/blob/master/examples/PGFPlots.jl.ipynb. |
That is fantastic! I really like the syntax. It is nice that the pgf macro can encapsulate GroupPlot code too. |
Oh, this is very nice. Is the idea to keep the colormap stuff in PGFPlots.jl or to have it in PGFPlotsX.jl (or whatever it is called)? I think PGFPlots.jl building on top of this would greatly simplify the code within PGFPlots.jl. |
Yeah, I think it makes sense to have one "low level" interface and then a more high level, user friendly interface built on top of that. |
In case you are interested, I started a bit on documentation: https://kristofferc.github.io/PGFPlotsX.jl/stable/index.html |
Cool! Should it eventually be brought into the https://github.com/JuliaPlots organization? |
Perhaps, but I think that is maybe mostly for the Plots.jl ecosystem? It even has the subtitle "Data visualization in Julia using Plots.jl" |
Oh, good point! |
Another idea is instead of building PGFPlots.jl on top of PGFPlotsX.jl, the two packages could just be merged. It feels a bit overkill to have two packages for something as specific as PGFPlots-plotting in Julia. This would keep documentation and tests in one place which I think would be more user friendly. |
I'm open to that. (Great meeting you yesterday!) |
Great to meet you too. Your talk was very interesting; thanks for keeping us safe while we are flying :) |
At the end of the day the PGFPlots.jl package needs to print the right property trees to a LaTeX document. Currently, many of the objects have a mix of specified properties (like
Linear
'sxmax
), and unspecified properties which can be set usingstyle
.Some types of plots, like bar blots, are not different plot types but differ instead merely by key parameters---the presence of "ybar" for instance. Often times we want to check whether a property has been set, or set a certain property, and the fact that fields like
style
are not parsed makes this a little difficult.One way to handle this is to have each plot type actually be a LaTeX property tree, kind of like JSON.
The text was updated successfully, but these errors were encountered: