Open gsahonero opened 1 year ago
Hi, thanks for looking into this. I modified the code to have a minimal working example to reproduce the issue.
I think this is a problem with PlotlyJS and how it deals with subplots. Apparently it does not preserves the layouts, as the subplot itself is a layout (i think). One quick solution would be to do something like this:
for k = 2:4
plotData.plot.layout[Symbol("yaxis$k")][:scaleanchor] = "x$k"
plotData.plot.layout[Symbol("yaxis$k")][:scaleratio] = 1
end
Not sure if there is something we can do to preserve the layouts when using subplots @beorostica ?
I believe this could be affecting other types of plots.
It is weird because it is preserving some information about the layout (?)
using KomaMRI
using PlotlyJS
slice_abs_1 = zeros(64,64)
max_scale = findmax([findmax(slice_abs_1)])[1][1]
firstPlotTrace = plot_image(slice_abs_1, title="darkmode=true", zmin=0, zmax=max_scale, darkmode=true);
secondPlotTrace = plot_image(slice_abs_1, title="darkmode=true", zmin=0, zmax=max_scale, darkmode=true);
thirdPlotTrace = plot_image(slice_abs_1, title="darkmode=false", zmin=0, zmax=max_scale, darkmode=false);
fourthPlotTrace = plot_image(slice_abs_1, title="darkmode=false", zmin=0, zmax=max_scale, darkmode=false);
plotData = [firstPlotTrace secondPlotTrace; thirdPlotTrace fourthPlotTrace];
for k = 2:4
plotData.plot.layout[Symbol("yaxis$k")][:scaleanchor] = "x$k"
plotData.plot.layout[Symbol("yaxis$k")][:scaleratio] = 1
end
display(plotData)
Hi,
In case it is useful, I ended up writing an "alternative" function using the plotly()
backend for Plots
instead of using several plot_image
calls:
function multiple_plots(images, titles, main_title, aspect_ratio; plot_params = Dict("colorbar"=>"individual"))
plotly()
plots = []
index = 1
if haskey(plot_params, "show_axis")
show_axis = plot_params["show_axis"]
else
show_axis = false
end
if haskey(plot_params, "show_grid")
show_grid = plot_params["show_grid"]
else
show_grid = false
end
if plot_params["colorbar"] == "global"
clims = extrema(vcat(images...))
if aspect_ratio != 1
if haskey(plot_params, "force_aspect_ratio")
if plot_params["force_aspect_ratio"] == true
println("Warning, forcing aspect ratio to be another value rather than 1.")
else
println("Making aspect ratio equal to 1, use plot_params[\"force_aspect_ratio\"]=true to avoid this.")
aspect_ratio = 1
end
else
println("Making aspect ratio equal to 1, use plot_params[\"force_aspect_ratio\"]=true to avoid this.")
aspect_ratio = 1
end
end
for image in images
plot_i = Plots.heatmap(image', color=:grays, aspect_ratio=aspect_ratio, showaxis = show_axis, grid = show_grid, title = titles[index], plot_titlevspan = 0.1, top_margin=10*Plots.px, clims=clims, colorbar=false)
push!(plots, plot_i)
index = index + 1
end
trace = clims[1]:0.01:clims[2]
display(Plots.plot(plots..., Plots.heatmap((trace).*ones(size(trace)[1],1), legend=:none, c=:grays, xticks=:none, yticks=(1:size(trace)[1]/10:size(trace)[1], string.(round.(LinRange(clims[1], clims[2], 10), digits=1)))), layout=@layout[grid(2,2) a{0.03w}], plot_title=main_title))
else
for image in images
plot_i = Plots.heatmap(image', color=:grays, aspect_ratio=aspect_ratio, showaxis = show_axis, grid = show_grid, title = titles[index], plot_titlevspan = 0.1, top_margin=10*Plots.px)
push!(plots, plot_i)
index = index + 1
end
display(Plots.plot(plots..., plot_title = main_title, plot_titlevspan=0.1))
end
end
A simple usage would be just:
using Plots
slice_abs_1 = zeros(64,64)
slice_abs_2 = zeros(64,64)
slice_abs_3 = zeros(64,64)
slice_abs_4 = zeros(64,64)
multiple_plots([slice_abs_1, slice_abs_2, slice_abs_3, slice_abs_4], ["1", "2", "3", "4"], "Multiple plots", 1.13; plot_params=Dict("colorbar"=>"global", "force_aspect_ratio"=>true, "show_axis"=>true, "show_grid" => true))
The result:
Some things I learned in the process and are unfortunately yet to be solved:
I guess that there should be another way to make this right, but so far I haven't dedicated too much time to it. Moreover, this function should work with any other "image" and it does not require Koma at all. But, that makes me wonder whether it would be a good idea to have a plot_images
function in Koma and solve this issue programmatically. Or, to make plot_image
compliant with aspect_ratio
changes for multi-plot figures? Or, if the recommendation should be to manually adjust aspect_ratio
while calling plot_image
?
Anyways, hope it is useful for anybody.
Hi,
When using the
SyncPlots
thatplot_image
returns to plot several images in a subplot manner, the aspect ratio of the last images is not respected. Is there a better way to make subplots usingplot_image
results?This code should reproduce the issue, where only the first
plot_image
works as expected (seeissue_1_1.png
andissue_1_2.png
, both generated by changing the size of the plotting window in VS Code and only the first image respecting the required aspect ratio), and the others do not. It also shows that the problem is similar to whenheatmap
is used (seeissue_1_3.png
, where all the plots change their aspect ratio).issue_1_1.png
:issue_1_2.png
:issue_1_3.png
:For context, I ran into this problem when using Windows 11, Julia 1.9.3, KomaMRI 0.7.4, PlotlyJS 0.18.10, and VS Code 1.84.2 (the code is executed using the terminal)