# Issue

I don’t know how to set `aspect_ratio=:equal` for 3d plot (like `axis_equal` in `MATLAB`).
It seems that only `x` and `y` axes’ aspect ratio are equal.

## Example code

``````using Plots

function test()
N = 10
xs = range(0, stop=10, length=N)
ys = range(0, stop=20, length=N)
zs = range(0, stop=50, length=N)
p = plot(; aspect_ratio=1.0)
plot!(xs, ys, zs)
end
test()
``````

## Result

@iHany, see revised improved solution using `gr()` backend below.

``````using Plots; gr(size=(600,600))

function plot_iso3d(xs, ys, zs; lw=3, lc=:red, title="Isometric 3D plot",label=false, camera=(45,30))
# condition data for nearly isometric 3D plot
x12, y12, z12 = extrema(xs), extrema(ys), extrema(zs)
d = maximum([diff([x12...]),diff([y12...]),diff([z12...])])[1] / 2
xm, ym, zm = mean(x12),  mean(y12),  mean(z12)

# plot data
p = Plots.plot(; xlabel="x",ylabel="y",zlabel="z", aspect_ratio=:equal, grid=:true)
Plots.plot!(xlims=(xm-d,xm+d), ylims=(ym-d,ym+d), zlims=(zm-d,zm+d))
Plots.plot!(;camera=camera)    #(azimuth,elevation) ???
Plots.plot!(xs, ys, zs, title=title,lw=lw,lc=lc,label=label)
Plots.plot!(xs, ys, zlims(p)[1] .+ 0*zs, lw=1, lc=:lightgray, label=false)
Plots.plot!(xs, ylims(p)[2]  .+ 0*ys, zs, lw=1, lc=:lightgray, label=false)
Plots.plot!(xlims(p)[1]  .+ 0*xs, ys, zs, lw=1, lc=:lightgray, label=false)
end

#input data
N = 100
xs = LinRange(0,40,N)
ys = LinRange(0,20,N) .+ 10*sin.(xs)
zs = LinRange(-10,50,N) .+ 15*sin.(xs)
plot_iso3d(xs, ys, zs)
``````

2 Likes

Minor addition: one thing that always bothered me about doing this sort of thing in Matlab was that it wouldn’t actually do the exact same thing as automatic axis limits, because it didn’t expose the limit widening algorithm.

In Julia,

``````plot(x, y; xlims=Plots.widen(xmin, xmax))
``````

gets rid of that problem. Just a bit of added sugar.

1 Like

Oh no, it’s the best? Seriously?

It works well but is quite uncomfortable

Anyhow, thanks

“improved” != best

There were related questions and PRs in github, etc…, the best solution is in the hands of Plots.jl code developers.

1 Like

Hi, I think that the key line of @rafael.guerra’s solution is:

``````using Plots; gr(size=(600,600))
``````

At least at first sight, it seems that the attribute `aspect_ratio=1.0` (or `aspect_ratio=:equal`) does work for 3d, but assumes that the figure canvas has square proportions – which is not true by default.

If you don’t want to reset the default figure size, you can also set it for a particular plot:

``````plot(x,y,z, aspect_ratio=1.0, size=(600,600))
``````

@heliosdrm, the key lines in the solution posted above lie immediately below the comment:

``````# condition data for nearly isometric 3D plot
...
``````

Maybe I’m understanding a different point from @iHany 's original question? I interpreted that the problem was that the Z axis in his example looked squashed with respect to the X and Y axes, in spite of having set the attribute `aspect_ratio=1.0`. My point was that the only that has to be done to see the Z axis with the desired proportion is adding `size=(600,600)` in the call to either `gr` or `plot`.

(Edit: or `size=(n,n)`, for whatever `n` is wanted).

That is obviously not enough, and will be data dependent.
For the original example given by OP, it will produce the plot below which is far from having aspect ratio = 1:

1 Like

You are right: silly oversight from my side.

1 Like