Skip to content
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

show method error when trying to use Cairo #372

Open
zaphar opened this issue Dec 15, 2019 · 8 comments
Open

show method error when trying to use Cairo #372

zaphar opened this issue Dec 15, 2019 · 8 comments

Comments

@zaphar
Copy link

zaphar commented Dec 15, 2019

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
@Mattriks
Copy link
Member

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.

@zaphar
Copy link
Author

zaphar commented Dec 17, 2019

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

@Mattriks
Copy link
Member

Did you try the new Compose.showmethod above? (I haven't yet) . If that works, I can open a PR here asap.

@zaphar
Copy link
Author

zaphar commented Dec 17, 2019

I have not yet. But I can try it out here in a few minutes :-D. I'll let you know if it works.

@zaphar
Copy link
Author

zaphar commented Dec 17, 2019

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

@Mattriks
Copy link
Member

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).

@Mattriks
Copy link
Member

Mattriks commented Dec 17, 2019

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 .

@Mattriks
Copy link
Member

See further investigation in JunoLab/Weave.jl#266

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants