From 4a36c94610a9e318e20995f9a660453053a1072b Mon Sep 17 00:00:00 2001 From: d-monnet Date: Mon, 30 Oct 2023 15:40:19 -0400 Subject: [PATCH] add figure export options provided by TizkPictures.jl export options are .tikz, .tex, .svg and .pdf --- Project.toml | 3 +- src/tikz_export.jl | 128 +++++++++++++++++++++++---------------------- test/runtests.jl | 16 ++++-- 3 files changed, 81 insertions(+), 66 deletions(-) diff --git a/Project.toml b/Project.toml index 5cfbd64..ea048c9 100644 --- a/Project.toml +++ b/Project.toml @@ -9,14 +9,15 @@ NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" Requires = "ae029012-a4dd-5104-9daa-d747884805df" Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +TikzPictures = "37f6aa50-8035-52d0-81c2-5a1d08754b2d" [compat] CSV = "0.10" LaTeXStrings = "^1.3" NaNMath = "0.3, 1" Requires = "1" -julia = "^1.6" Tables = "1.11" +julia = "^1.6" [extras] PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925" diff --git a/src/tikz_export.jl b/src/tikz_export.jl index 1ab2437..1f1908b 100644 --- a/src/tikz_export.jl +++ b/src/tikz_export.jl @@ -1,3 +1,5 @@ +using TikzPictures + export export_performance_profile_tikz """ @@ -13,6 +15,7 @@ Export tikz figure of the performance profiles given by `T` in `filename`. ## Keyword Arguments +* `file_type = TIKZ` : type of exported file. Options are `TIKZ`(raw tikz code), `TEX`(embeded tikz code, ready to compile), `SVG`, `PDF`. * `solvernames :: Vector{String} = []` : names of the solvers, should have as many elements as the number of columns of `T`. If empty, use the labels returned by `performance_profile_axis_labels`. * `xlim::AbstractFloat=10.` : size of the figure along the x axis. /!\\ the legend is added on the right hand side of the figure. * `ylim::AbstractFloat=10.` : size of the figure along the y axis. @@ -30,13 +33,14 @@ Export tikz figure of the performance profiles given by `T` in `filename`. * `lgd_v_offset::AbstractFloat = 0.7` : vertical space between two legend items. * `lgd_plot_offset::AbstractFloat = 0.1` : space between legend box left side and curve plot. * `lgd_box_length::AbstractFloat = 3.` : legend box horizontal length. -* `label_val::Vector = [0.2,0.25,0.5,1]` : possible graduation labels along axes are multiples of label_val elements times 10^n (n is automatically selected). +* `label_val::Vector = [0.2,0.25,0.5,1]` : possible graduation labels along axes are multiples of label_val elements times 10^n (n is automatically selected). Other keyword arguments are passed to `performance_profile_data`. """ function export_performance_profile_tikz( T::Matrix{Float64}, filename::String; + file_type = TIKZ, solvernames::Vector{String}=String[], xlim::AbstractFloat=10., ylim::AbstractFloat=10., @@ -58,8 +62,6 @@ function export_performance_profile_tikz( label_val::Vector = [0.2,0.25,0.5,1], kwargs...) - - logscale = true if haskey(kwargs,:logscale) logscale = kwargs[:logscale] @@ -96,70 +98,72 @@ function export_performance_profile_tikz( xratio = xlim/xmax yratio = ylim/ymax - open(filename, "w") do io - println(io, "\\begin{tikzpicture}") - # axes - println(io, "\\draw[line width=$linewidth] (0,0) -- ($xlim,0);") - println(io, "\\node at ($(xlim/2), -1) {$xlabel};") - println(io, "\\draw[line width=$linewidth] (0,0) -- (0,$ylim);") - println(io, "\\node at (-1,$(ylim/2)) [rotate = 90] {$ylabel};") - # axes graduations and labels, - if logscale - for i in eachindex(x_grad) - println(io, "\\draw[line width=$linewidth] ($(x_grad[i]*xratio),0) -- ($(x_grad[i]*xratio),$axis_tick_length) node [pos=0, below] {\$2^{$(to_int(x_grad[i]))}\$};") - end - else - for i in eachindex(x_grad) - println(io, "\\draw[line width=$linewidth] ($(x_grad[i]*xratio),0) -- ($(x_grad[i]*xratio),$axis_tick_length) node [pos=0, below] {$(to_int(x_grad[i]))};") - end + io = IOBuffer() + + # axes + println(io, "\\draw[line width=$linewidth] (0,0) -- ($xlim,0);") + println(io, "\\node at ($(xlim/2), -1) {$xlabel};") + println(io, "\\draw[line width=$linewidth] (0,0) -- (0,$ylim);") + println(io, "\\node at (-1,$(ylim/2)) [rotate = 90] {$ylabel};") + # axes graduations and labels, + if logscale + for i in eachindex(x_grad) + println(io, "\\draw[line width=$linewidth] ($(x_grad[i]*xratio),0) -- ($(x_grad[i]*xratio),$axis_tick_length) node [pos=0, below] {\$2^{$(to_int(x_grad[i]))}\$};") end - for i in eachindex(y_grad) - println(io, "\\draw[line width=$linewidth] (0,$(y_grad[i]*yratio)) -- ($axis_tick_length,$(y_grad[i]*yratio)) node [pos=0, left] {$(to_int(y_grad[i]))};") + else + for i in eachindex(x_grad) + println(io, "\\draw[line width=$linewidth] ($(x_grad[i]*xratio),0) -- ($(x_grad[i]*xratio),$axis_tick_length) node [pos=0, below] {$(to_int(x_grad[i]))};") end - # grid - if grid - for i in eachindex(x_grad) - println(io, "\\draw[gray] ($(x_grad[i]*xratio),0) -- ($(x_grad[i]*xratio),$ylim);") - end - for i in eachindex(y_grad) - println(io, "\\draw[gray] (0,$(y_grad[i]*yratio)) -- ($xlim,$(y_grad[i]*yratio)) node [pos=0, left] {$(to_int(y_grad[i]))};") - end + end + for i in eachindex(y_grad) + println(io, "\\draw[line width=$linewidth] (0,$(y_grad[i]*yratio)) -- ($axis_tick_length,$(y_grad[i]*yratio)) node [pos=0, left] {$(to_int(y_grad[i]))};") + end + # grid + if grid + for i in eachindex(x_grad) + println(io, "\\draw[gray] ($(x_grad[i]*xratio),0) -- ($(x_grad[i]*xratio),$ylim);") + end + for i in eachindex(y_grad) + println(io, "\\draw[gray] (0,$(y_grad[i]*yratio)) -- ($xlim,$(y_grad[i]*yratio)) node [pos=0, left] {$(to_int(y_grad[i]))};") end + end - # profiles - for j in eachindex(solvernames) - drawcmd = "\\draw[line width=$linewidth, $(colours[j]), $(linestyles[j]), line width = $linewidth] " - drawcmd *= "($(x_mat[1,j]*xratio),$(y_mat[1,j]*yratio))" - for k in 2:size(x_mat,1) - if isnan(x_mat[k,j]) - break - end - if y_mat[k,j] > 1 # for some reasons last point of profile is set with y=1.1 by data function... - drawcmd *= " -- ($(xmax*xratio),$(y_mat[k-1,j]*yratio)) -- ($(xmax*xratio),$(y_mat[k-1,j]*yratio))" - else - # if !isempty(markers) - # drawcmd *= " -- ($(x_mat[k,j]*xratio),$(y_mat[k-1,j]*yratio)) node[$(colours[j]),draw,$(markers[j]),solid] {} -- ($(x_mat[k,j]*xratio),$(y_mat[k,j]*yratio))" - # else - drawcmd *= " -- ($(x_mat[k,j]*xratio),$(y_mat[k-1,j]*yratio)) -- ($(x_mat[k,j]*xratio),$(y_mat[k,j]*yratio))" - # end - end + # profiles + for j in eachindex(solvernames) + drawcmd = "\\draw[line width=$linewidth, $(colours[j]), $(linestyles[j]), line width = $linewidth] " + drawcmd *= "($(x_mat[1,j]*xratio),$(y_mat[1,j]*yratio))" + for k in 2:size(x_mat,1) + if isnan(x_mat[k,j]) + break + end + if y_mat[k,j] > 1 # for some reasons last point of profile is set with y=1.1 by data function... + drawcmd *= " -- ($(xmax*xratio),$(y_mat[k-1,j]*yratio)) -- ($(xmax*xratio),$(y_mat[k-1,j]*yratio))" + else + # if !isempty(markers) + # drawcmd *= " -- ($(x_mat[k,j]*xratio),$(y_mat[k-1,j]*yratio)) node[$(colours[j]),draw,$(markers[j]),solid] {} -- ($(x_mat[k,j]*xratio),$(y_mat[k,j]*yratio))" + # else + drawcmd *= " -- ($(x_mat[k,j]*xratio),$(y_mat[k-1,j]*yratio)) -- ($(x_mat[k,j]*xratio),$(y_mat[k,j]*yratio))" + # end end - drawcmd *= ";" - println(io,drawcmd) - end - # legend - for j in eachindex(solvernames) - legcmd = "\\draw[$(colours[j]), $(linestyles[j]), line width = $linewidth] " - legcmd *= "($(lgd_pos[1]+lgd_plot_offset),$(lgd_pos[2]-j*lgd_v_offset)) -- ($(lgd_pos[1]+lgd_plot_offset+lgd_plot_length),$(lgd_pos[2]-j*lgd_v_offset)) node [black,pos=1,right] {$(String(solvernames[j]))}" - # if !isempty(markers) - # legcmd *= " node [midway,draw,$(markers[j]),solid] {}" - # end - legcmd *= ";" - - println(io,legcmd) end - # legend box - println(io,"\\draw[line width=$linewidth] ($(lgd_pos[1]),$(lgd_pos[2])) -- ($(lgd_pos[1]+lgd_box_length),$(lgd_pos[2])) -- ($(lgd_pos[1]+lgd_box_length),$(lgd_pos[2]-lgd_v_offset*(length(solvernames)+1))) -- ($(lgd_pos[1]),$(lgd_pos[2]-lgd_v_offset*(length(solvernames)+1))) -- cycle;") - println(io,"\\end{tikzpicture}") + drawcmd *= ";" + println(io,drawcmd) end + # legend + for j in eachindex(solvernames) + legcmd = "\\draw[$(colours[j]), $(linestyles[j]), line width = $linewidth] " + legcmd *= "($(lgd_pos[1]+lgd_plot_offset),$(lgd_pos[2]-j*lgd_v_offset)) -- ($(lgd_pos[1]+lgd_plot_offset+lgd_plot_length),$(lgd_pos[2]-j*lgd_v_offset)) node [black,pos=1,right] {$(String(solvernames[j]))}" + # if !isempty(markers) + # legcmd *= " node [midway,draw,$(markers[j]),solid] {}" + # end + legcmd *= ";" + + println(io,legcmd) + end + # legend box + println(io,"\\draw[line width=$linewidth] ($(lgd_pos[1]),$(lgd_pos[2])) -- ($(lgd_pos[1]+lgd_box_length),$(lgd_pos[2])) -- ($(lgd_pos[1]+lgd_box_length),$(lgd_pos[2]-lgd_v_offset*(length(solvernames)+1))) -- ($(lgd_pos[1]),$(lgd_pos[2]-lgd_v_offset*(length(solvernames)+1))) -- cycle;") + + raw_code = String(take!(io)) + tp = TikzPicture(raw_code) + save(file_type(filename),tp) end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 5dfc80f..43f0ae8 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,7 @@ using BenchmarkProfiles using LaTeXStrings using Test +using TikzPictures @testset "powertick" begin @test BenchmarkProfiles.powertick("15") == "2¹⁵" @@ -75,9 +76,18 @@ if !Sys.isfreebsd() # GR_jll not available, so Plots won't install @testset "tikz export" begin T = 10 * rand(25, 3) - filename = "tikz_fig.tex" + filename = "tikz_fig" export_performance_profile_tikz(T,filename) - @test isfile(filename) - rm(filename) + @test isfile(filename * ".tikz") + rm(filename * ".tikz") + export_performance_profile_tikz(T,filename,file_type = TEX) + @test isfile(filename * ".tex") + rm(filename * ".tex") + export_performance_profile_tikz(T,filename,file_type = SVG) + @test isfile(filename * ".svg") + rm(filename * ".svg") + export_performance_profile_tikz(T,filename,file_type = PDF) + @test isfile(filename * ".pdf") + rm(filename * ".pdf") end end