 # Plots GR axis break

Is it possible to plot a figure containing axis break like this using Plots.jl and GR backend?

Especially in boxplot.

Never saw such type of example done with `gr()`, but you may try to implement it using the same subplot trick as done here by @ianshmean

Using the subplot trick mentioned above, the following plots with breaks can be obtained using `gr()` back-end, but the code is a bit shaky:

Using gr’s ggplot2 theme with no breaks: Using gr’s ggplot2 theme with breaks:

``````xb = [(500,800), (1900,2100)]
yb = [(100,300), (500,650), (850,900)]
``````

Using gr’s dark theme with breaks:

Using gr’s dark theme with breaks, but in log-log scale:

Using gr’s ggplot2 theme with 1 ybreak:

``````xb = []   # empty set for no breaks
yb = [(100,300)]
``````

Here below the code, with a user function `breakplot()` defined:

``````using Measures, Plots; gr()

function breakplot(X,Y,xb,yb; lc=:yellow,lw=3,ls=:solid,xlabel="X-axis",ylabel="Y-axis",ptheme=:dark,
xscale=:identity, yscale=:identity, size = (1000,700))
# by @rafael.guerra

if occursin("dark",lowercase(string(ptheme)))
gc =:white
else
gc =:black
end
nx, ny = length(xb), length(yb)

xb2 = [X; collect(Iterators.flatten(xb)); X[end]]
yb2 = [minimum(Y); collect(Iterators.flatten(yb)); maximum(Y)]

w = [diff(xb2[2(i-1)+1:2*i]) for i in 1:nx+1]
if occursin("log10",lowercase(string(xscale)))
w = log10.(w)
end
w = w / sum(w)

h = [diff(yb2[2(i-1)+1:2*i]) for i in 1:ny+1]
if occursin("log10",lowercase(string(yscale)))
h = log10.(h)
end
h = reverse(h) / sum(h)

theme(ptheme)
l = @layout [a{0.001w} [grid(ny+1,nx+1, heights=h, widths=w); b{0.001h}]]  # first & last subplots for axes labels
p = fill(plot( lw=lw,ls=ls), 1 + (ny+1) * (nx+1) + 1)

p = plot(ylabel=ylabel, guidefont=font(10,gc),guide_position=:right,showaxis=false,xticks=false,yticks=false,margin=5mm)
for j in 1:ny+1
jj = (ny+1) - j + 1
ylj = yb2[2(j-1)+1:2*j]
for i in 1:nx+1
xli = xb2[2(i-1)+1:2*i]
ix = (jj-1)*(nx+1) + i
if (i == 1) & (j != 1)
p[1+ix] = plot(X,Y, xlims=xli, ylims=ylj,framestyle=:default,legend=false,margin=0mm,lc=lc,tickfontsize=6,
xshowaxis=false,xticks=false,xscale=xscale,yscale=yscale, size=(size*h[j],size*w[i]))
elseif (i != 1) & (j == 1)
showaxis=:x
p[1+ix] = plot(X,Y, xlims=xli, ylims=ylj,framestyle=:default,legend=false,margin=0mm,lc=lc,tickfontsize=6,
yshowaxis=false,yticks=false,xscale=xscale,yscale=yscale, size=(size*h[j],size*w[i]))
elseif (i == 1) & (j == 1)
p[1+ix] = plot(X,Y, xlims=xli, ylims=ylj,framestyle=:default,legend=false,margin=0mm,lc=lc,tickfontsize=6,
xscale=xscale,yscale=yscale, size=(size*h[j],size*w[i]))
else
p[1+ix] = plot(X,Y, xlims=xli, ylims=ylj,framestyle=nothing,legend=false,margin=0mm,lc=lc,showaxis=false,
xticks=false,yticks=false,xscale=xscale,yscale=yscale, size=(size*h[j],size*w[i]))
end
end
end
p[end] = plot(xlabel=xlabel, guidefont=font(10,gc),guide_position=:top,showaxis=false,xticks=false,yticks=false,margin=5mm)

plot(p..., layout=l, grid=false, size=size)
end

# Examples:
X = 1:2500.0
Y = 1000*(sin.(X/500)).^2 .+ 1

xb = [(500,800), (1900,2100)]
yb = [(100,300), (500,650), (850,900)]

theme(:default)
plot(X,Y, xlabel="Time [min]",ylabel="Trajectory altitude [m]", legend=false)

breakplot(X,Y,xb,yb; lc=:blue, xlabel="Time [min]",ylabel="Trajectory altitude [m]",ptheme=:ggplot2)

breakplot(X,Y,xb,yb; lc=:yellow, xlabel="Time [min]",ylabel="Trajectory altitude [m]")

breakplot(X,Y,xb,yb; lc=:yellow, xlabel="Time [min]",ylabel="Trajectory altitude [m]", xscale=:log10,yscale=:log10)

xb = []   # empty set for no breaks
yb = [(100,300)]
breakplot(X,Y,xb,yb; lc=:blue, xlabel="Time [min]",ylabel="Trajectory altitude [m]",ptheme=:ggplot2)

``````

Can you share an example or any link?

@iHany, as requested the user function code and examples were updated above.
As indicated, this subplot business in Plots.jl and `gr()` is a bit shaky…
If you see things that can be obviously improved, please do share.

NB: there was a bug on the list of vertical proportions which were in reverse order. Fixed now.

1 Like

Ok…
I think that your remedy works fine but it needs additional efforts as you said.
It seems that there are already some issues reported in Plots.jl such as this, so subplot method would be the best for now.

Thanks for sharing your example 