Hi all,
I’m making a plot using Plots.jl
with the default GR backend.
When I run this code
# density_matrix contains the data I want to plot
p = plot(density_matrix, st = :surface, xlabel="Binary weight", ylabel="Power",
zlabel="Density",
zlims=(0,200),
c=cgrad(:heat, scale = :exp),
) # create surface
gui()
I obtain this nice plot:
However, if I change the camera, like here:
p = plot(density_matrix, st = :surface, xlabel="Binary weight", ylabel="Power",
zlabel="Density",
zlims=(0,200),
c=cgrad(:heat, scale = :exp),
camera = (-45,50) # NOTE HERE
) # create surface
gui()
I get:
Now, I want this angle for the camera, but as you see the axis are all misplaced. How can I move them?
Thanks!
I may have found a trick I think you can try to overcome the current limitation of Plots.jl gr() for negative camera azimuths, which hides the axes behind the surface.
using Plots; gr(dpi=600)
f(x,y) = x.^3 .* y'
x = range(0,3,100)
y = range(0,40,200)
θ = 60 # camera azimuth [deg]
# Positive camera azimuth, axes OK:
Plots.surface(x, y, f, zlim=(0,30), clim=(0,30), camera=(θ,50), framestyle=:box)
# Axes hidden for negative camera azimuth:
Plots.surface(x, y, f, zlim=(0,30), clim=(0,30), camera=(-θ,50), framestyle=:box)
# Trick to get the axes to the front:
g(y,x) = f(x,y)
Plots.surface(y, x, g, xflip=true, zlim=(0,30), clim=(0,30), camera=(90 - θ,50), framestyle=:box, title="equivalent of camera=(-$θ, 50)")
2 Likes
Thanks, it kinda works but correct me if I’m wrong: I also need to switch xlabel
and ylabel
, right?
Then it works, thanks! Seems like quite a bug of the GR backend tho. Where should I report it?
1 Like
You can create a new issue here:
2 Likes
Thanks, I will, also because with this workaround I perform KDE on the other dimension ("Power"
instead of "Binary weight"
), which is something I wanted to preserve
Edit: nevermind, I realised this happened also with the “usual” plot, so I probably misinterpreted the plot or performed the KDE wrongly, anyway it shouldn’t be an issue of Plots.jl
Perhaps I am missing something, but if we have as input a density_matrix
(instead of a function as in my example), then we only need to plot the transpose with the xflip
and 90-θ
azimuth.
Try for example:
Plots.surface(transpose(density_matrix), xflip=true, zlim=(0,30), clim=(0,30), camera=(90 - θ,50), framestyle=:box, title="equivalent of camera=(-$θ, 50)")
It’s what I did:
transposed_matrix = transpose(density_matrix)
p = plot(transposed_matrix, st = :surface, title=plot_title,
ylabel="Binary weight", xlabel="Power", # inverted as well
zlabel="Density",
xflip=true,
dpi=500,
# zlims=(0,200),
c=cgrad(:heat, scale = :exp),
camera = (45,50)
) # create surface
plus I switched the labels.
This is better than the hack I just came up with in 99% of situations, but if anyone is picky like me about not wanting to edit the data (and potentially mess it up) before plotting it, you can try this function I made.
BE FOREWARNED: IT TRULY IS AN UGLY, DIRTY HACK AND @rafael.guerra’s SOLUTION IS LIKELY THE LESSER OF TWO EVILS.