Compose.jl
Compose.jl copied to clipboard
show method error when trying to use Cairo
Cairo and Compose appear to be having some issues regarding the show method. I'm attempting to generate some pdf's using Weave.jl and this sample code block I'm putting below generates a complaint thinking the Cairo and/or Fontconfig packages are not installed. It seems to be due to a problem with the show method which I'm assuming Cairo is supposed to provide but Compose can't see it.
I thought at first maybe I was having a problem with precompilation but even after blowing away the precompile cache I'm still getting the error.
I'm using current head for both Compose and Gadfly packages.
import Cairo, Fontconfig
using Gadfly
p1 = plot([sin,cos], 0, 2pi)
p2 = plot((x,y)->sin(x)+cos(y), 0, 2pi, 0, 2pi)
p3 = spy(ones(33)*sin.(0:(pi/16):2pi)' + cos.(0:(pi/16):2pi)*ones(33)')
hstack(p1,p2,p3)
The error and stacktrace are below.
Add them with the package manager if necessary, then run `import Cairo,
Fontconfig` before invoking `show(::IO, ::MIME"application/pdf", ::Context)`.
Stacktrace:
[1] error(::String) at ./error.jl:33
[2] show(::Base.GenericIOBuffer{Array{UInt8,1}}, ::MIME{Symbol("application/pdf")}, ::Compose.Context) at /home/jwall/lib/julia/playground/dev/Compose/src/Compose.jl:141
[3] __binrepr(::MIME{Symbol("application/pdf")}, ::Compose.Context, ::Nothing) at ./multimedia.jl:157
[4] _binrepr(::MIME{Symbol("application/pdf")}, ::Compose.Context, ::Nothing) at ./multimedia.jl:163
[5] #repr#1(::Nothing, ::typeof(repr), ::MIME{Symbol("application/pdf")}, ::Compose.Context) at ./multimedia.jl:145
[6] repr(::MIME{Symbol("application/pdf")}, ::Compose.Context) at ./multimedia.jl:145
[7] (::Weave.var"#30#31"{Compose.Context,MIME{Symbol("application/pdf")},String})(::IOStream) at /home/jwall/.julia/packages/Weave/UOxmI/src/display_methods.jl:138
[8] #open#271(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(open), ::Weave.var"#30#31"{Compose.Context,MIME{Symbol("application/pdf")},String}, ::String, ::Vararg{String,N} where N) at ./io.jl:298
[9] open(::Function, ::String, ::String) at ./io.jl:296
[10] add_figure(::Weave.Report, ::Compose.Context, ::MIME{Symbol("application/pdf")}, ::String) at /home/jwall/.julia/packages/Weave/UOxmI/src/display_methods.jl:136
[11] display(::Weave.Report, ::MIME{Symbol("application/pdf")}, ::Compose.Context) at /home/jwall/.julia/packages/Weave/UOxmI/src/display_methods.jl:78
[12] display(::Weave.Report, ::String, ::Any) at ./multimedia.jl:214
[13] #invokelatest#1 at ./essentials.jl:709 [inlined]
[14] invokelatest at ./essentials.jl:708 [inlined]
[15] display(::Weave.Report, ::Compose.Context) at /home/jwall/.julia/packages/Weave/UOxmI/src/display_methods.jl:53
[16] display(::Any) at ./multimedia.jl:323
[17] capture_output(::Expr, ::Module, ::Bool, ::Bool, ::Bool, ::Bool) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:238
[18] run_code(::Weave.CodeChunk, ::Weave.Report, ::Module) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:208
[19] eval_chunk(::Weave.CodeChunk, ::Weave.Report, ::Module) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:289
[20] run_chunk(::Weave.CodeChunk, ::Weave.WeaveDoc, ::Weave.Report, ::Module) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:130
[21] #run#34(::String, ::Symbol, ::Symbol, ::Dict{Any,Any}, ::String, ::Nothing, ::String, ::Symbol, ::Bool, ::typeof(run), ::Weave.WeaveDoc) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:94
[22] (::Base.var"#kw##run")(::NamedTuple{(:doctype, :mod, :out_path, :args, :fig_path, :fig_ext, :cache_path, :cache, :throw_errors),Tuple{String,Symbol,Symbol,Dict{Any,Any},String,Nothing,String,Symbol,Bool}}, ::typeof(run), ::Weave.WeaveDoc) at ./none:0
[23] #weave#16(::String, ::Symbol, ::Symbol, ::Dict{Any,Any}, ::Symbol, ::String, ::Nothing, ::String, ::Symbol, ::Bool, ::Nothing, ::Nothing, ::Nothing, ::Array{String,1}, ::String, ::typeof(weave), ::String) at /home/jwall/.julia/packages/Weave/UOxmI/src/Weave.jl:121
[24] (::Weave.var"#kw##weave")(::NamedTuple{(:doctype, :throw_errors),Tuple{String,Bool}}, ::typeof(weave), ::String) at ./none:0
[25] build_weave_file(::String, ::String) at /home/jwall/lib/julia/playground/weave_build.jl:21
[26] top-level scope at /home/jwall/lib/julia/playground/weave_build.jl:30
[27] include at ./boot.jl:328 [inlined]
[28] include_relative(::Module, ::String) at ./loading.jl:1105
[29] include(::Module, ::String) at ./Base.jl:31
[30] exec_options(::Base.JLOptions) at ./client.jl:287
[31] _start() at ./client.jl:460
The issue here is that show(::IO, ::MIME"application/pdf", ::Context) hasn't been defined in Compose.
A generic show for Cairo output has been defined but it (incorrectly) calls the error string you found.
Note a specific show method has been defined for PNG here.
I don't use Weave.jl so I'm guessing that if you can change the figure output to PNG in Weave, it might work.
Alternatively, you might try this:
using Compose
Compose.show(io::IO, ::MIME"application/pdf", ctx::Context) =
draw(PDF(io, default_graphic_width, default_graphic_height), ctx)
and then run Weave. But I don't know what show output Weave wants for pdf. If it doesn't work I'll have to investigate Weave.jl.
Ahhh yeah that would explain it. I'll see if I can change the figure output as a workaround. I should probably also suggest to Weave that it warn users when they are attempting to do pdf output with Gadfly and Compose
Did you try the new Compose.showmethod above? (I haven't yet) . If that works, I can open a PR here asap.
I have not yet. But I can try it out here in a few minutes :-D. I'll let you know if it works.
It fails but it definitely got farther. Weave complains about default_graphic_width not being defined. More detailed stacktrace can be found below.
ERROR: LoadError: UndefVarError: default_graphic_width not defined
Stacktrace:
[1] capture_output(::Expr, ::Module, ::Bool, ::Bool, ::Bool, ::Bool) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:241
[2] run_code(::Weave.CodeChunk, ::Weave.Report, ::Module) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:208
[3] eval_chunk(::Weave.CodeChunk, ::Weave.Report, ::Module) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:289
[4] run_chunk(::Weave.CodeChunk, ::Weave.WeaveDoc, ::Weave.Report, ::Module) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:130
[5] #run#34(::String, ::Symbol, ::Symbol, ::Dict{Any,Any}, ::String, ::String, ::String, ::Symbol, ::Bool, ::typeof(run), ::Weave.WeaveDoc) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:94
[6] (::Base.var"#kw##run")(::NamedTuple{(:doctype, :mod, :out_path, :args, :fig_path, :fig_ext, :cache_path, :cache, :throw_errors),Tuple{String,Symbol,Symbol,Dict{Any,Any},String,String,String,Symbol,Bool}}, ::typeof(run), ::Weave.WeaveDoc) at ./none:0
[7] #weave#16(::String, ::Symbol, ::Symbol, ::Dict{Any,Any}, ::Symbol, ::String, ::Nothing, ::String, ::Symbol, ::Bool, ::Nothing, ::Nothing, ::Nothing, ::Array{String,1}, ::String, ::typeof(weave), ::String) at /home/jwall/.julia/packages/Weave/UOxmI/src/Weave.jl:121
[8] (::Weave.var"#kw##weave")(::NamedTuple{(:doctype, :throw_errors),Tuple{String,Bool}}, ::typeof(weave), ::String) at ./none:0
[9] build_weave_file(::String, ::String) at /home/jwall/lib/julia/playground/weave_build.jl:21
[10] top-level scope at /home/jwall/lib/julia/playground/weave_build.jl:30
[11] include at ./boot.jl:328 [inlined]
[12] include_relative(::Module, ::String) at ./loading.jl:1105
[13] include(::Module, ::String) at ./Base.jl:31
[14] exec_options(::Base.JLOptions) at ./client.jl:287
[15] _start() at ./client.jl:460
in expression starting at /home/jwall/lib/julia/playground/weave_build.jl:27
caused by [exception 2]
UndefVarError: default_graphic_width not defined
Stacktrace:
[1] display(::Weave.Report, ::Compose.Context) at /home/jwall/.julia/packages/Weave/UOxmI/src/display_methods.jl:60
[2] display(::Any) at ./multimedia.jl:323
[3] capture_output(::Expr, ::Module, ::Bool, ::Bool, ::Bool, ::Bool) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:238
[4] run_code(::Weave.CodeChunk, ::Weave.Report, ::Module) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:208
[5] eval_chunk(::Weave.CodeChunk, ::Weave.Report, ::Module) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:289
[6] run_chunk(::Weave.CodeChunk, ::Weave.WeaveDoc, ::Weave.Report, ::Module) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:130
[7] #run#34(::String, ::Symbol, ::Symbol, ::Dict{Any,Any}, ::String, ::String, ::String, ::Symbol, ::Bool, ::typeof(run), ::Weave.WeaveDoc) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:94
[8] (::Base.var"#kw##run")(::NamedTuple{(:doctype, :mod, :out_path, :args, :fig_path, :fig_ext, :cache_path, :cache, :throw_errors),Tuple{String,Symbol,Symbol,Dict{Any,Any},String,String,String,Symbol,Bool}}, ::typeof(run), ::Weave.WeaveDoc) at ./none:0
[9] #weave#16(::String, ::Symbol, ::Symbol, ::Dict{Any,Any}, ::Symbol, ::String, ::Nothing, ::String, ::Symbol, ::Bool, ::Nothing, ::Nothing, ::Nothing, ::Array{String,1}, ::String, ::typeof(weave), ::String) at /home/jwall/.julia/packages/Weave/UOxmI/src/Weave.jl:121
[10] (::Weave.var"#kw##weave")(::NamedTuple{(:doctype, :throw_errors),Tuple{String,Bool}}, ::typeof(weave), ::String) at ./none:0
[11] build_weave_file(::String, ::String) at /home/jwall/lib/julia/playground/weave_build.jl:21
[12] top-level scope at /home/jwall/lib/julia/playground/weave_build.jl:30
[13] include at ./boot.jl:328 [inlined]
[14] include_relative(::Module, ::String) at ./loading.jl:1105
[15] include(::Module, ::String) at ./Base.jl:31
[16] exec_options(::Base.JLOptions) at ./client.jl:287
[17] _start() at ./client.jl:460
caused by [exception 1]
UndefVarError: default_graphic_width not defined
Stacktrace:
[1] show at ./none:1 [inlined]
[2] __binrepr at ./multimedia.jl:157 [inlined]
[3] _binrepr at ./multimedia.jl:163 [inlined]
[4] #repr#1(::Nothing, ::typeof(repr), ::MIME{Symbol("application/pdf")}, ::Compose.Context) at ./multimedia.jl:145
[5] repr at ./multimedia.jl:145 [inlined]
[6] (::Weave.var"#30#31"{Compose.Context,MIME{Symbol("application/pdf")},String})(::IOStream) at /home/jwall/.julia/packages/Weave/UOxmI/src/display_methods.jl:138
[7] #open#271(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(open), ::Weave.var"#30#31"{Compose.Context,MIME{Symbol("application/pdf")},String}, ::String, ::Vararg{String,N} where N) at ./io.jl:298
[8] open at ./io.jl:296 [inlined]
[9] add_figure(::Weave.Report, ::Compose.Context, ::MIME{Symbol("application/pdf")}, ::String) at /home/jwall/.julia/packages/Weave/UOxmI/src/display_methods.jl:136
[10] display(::Weave.Report, ::MIME{Symbol("application/pdf")}, ::Compose.Context) at /home/jwall/.julia/packages/Weave/UOxmI/src/display_methods.jl:78
[11] display(::Weave.Report, ::String, ::Any) at ./multimedia.jl:214
[12] #invokelatest#1 at ./essentials.jl:709 [inlined]
[13] invokelatest at ./essentials.jl:708 [inlined]
[14] display(::Weave.Report, ::Compose.Context) at /home/jwall/.julia/packages/Weave/UOxmI/src/display_methods.jl:53
[15] display(::Any) at ./multimedia.jl:323
[16] capture_output(::Expr, ::Module, ::Bool, ::Bool, ::Bool, ::Bool) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:238
[17] run_code(::Weave.CodeChunk, ::Weave.Report, ::Module) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:208
[18] eval_chunk(::Weave.CodeChunk, ::Weave.Report, ::Module) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:289
[19] run_chunk(::Weave.CodeChunk, ::Weave.WeaveDoc, ::Weave.Report, ::Module) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:130
[20] #run#34(::String, ::Symbol, ::Symbol, ::Dict{Any,Any}, ::String, ::String, ::String, ::Symbol, ::Bool, ::typeof(run), ::Weave.WeaveDoc) at /home/jwall/.julia/packages/Weave/UOxmI/src/run.jl:94
[21] (::Base.var"#kw##run")(::NamedTuple{(:doctype, :mod, :out_path, :args, :fig_path, :fig_ext, :cache_path, :cache, :throw_errors),Tuple{String,Symbol,Symbol,Dict{Any,Any},String,String,String,Symbol,Bool}}, ::typeof(run), ::Weave.WeaveDoc) at ./none:0
[22] #weave#16(::String, ::Symbol, ::Symbol, ::Dict{Any,Any}, ::Symbol, ::String, ::Nothing, ::String, ::Symbol, ::Bool, ::Nothing, ::Nothing, ::Nothing, ::Array{String,1}, ::String, ::typeof(weave), ::String) at /home/jwall/.julia/packages/Weave/UOxmI/src/Weave.jl:121
[23] (::Weave.var"#kw##weave")(::NamedTuple{(:doctype, :throw_errors),Tuple{String,Bool}}, ::typeof(weave), ::String) at ./none:0
[24] build_weave_file(::String, ::String) at /home/jwall/lib/julia/playground/weave_build.jl:21
[25] top-level scope at /home/jwall/lib/julia/playground/weave_build.jl:30
[26] include at ./boot.jl:328 [inlined]
[27] include_relative(::Module, ::String) at ./loading.jl:1105
[28] include(::Module, ::String) at ./Base.jl:31
[29] exec_options(::Base.JLOptions) at ./client.jl:287
[30] _start() at ./client.jl:460
I put this chunk in a jmd file, and it works:
import Cairo
using Compose
img = compose(context(),
(context(units=UnitBox(0, 1.2, 1, -1)), circle(0.70, 0.75, 0.2), fill("gold"),
(context(), rectangle(), fill("transparent"), stroke("black")))
)
draw(PDF(), img);
The Compose.show method above will simply call the draw for you. So now I just need to figure out how Weave handles variables defined inside a module (Compose.default_graphic_width, Compose.default_graphic_height).
I tested the Compose.show method above in a Compose branch, and while it works, in the weaved pdf, each figure gets printed twice - further investigation needed!
For now, the workaround is to explicitly include the draw function in the code chunk e.g.
draw(PDF(), hstack(p1, p2));. Note that draw is only needed for hstacked (or vstacked) plots, single Gadfly plots work fine without it .
See further investigation in Junolab/Weave.jl#266