You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I was trying to crack why Plots layouting does not always work perfectly and stumbled upon the 2016 year Toms issues and how he had in mind in the first place. I believe not many people to this day understand exactly how layouting works.
Perhaps, it would be a good idea to have comprehensive developer docs http://docs.juliaplots.org/latest/pipeline/ and explain concepts thoroughly with linking relevant code. But this is a digression, better documentation is always desired and all packages.
This is relevant to GR and PyPlot any other backend that would use _update_min_padding! callback. Upon conservation with @BeastyBlacksmith I learned that pgfplotsx handles this a little differently
First of all, let us start with an example
p1 = plot(rand(10));
p2= plot(rand(10));
p3 = plot(rand(10));
p4 = plot(rand(10));
plot(p1,p2,p3,p4) # looking well and good
Issues reporting the same things: (perhaps should be deleted to keep things cleaner): #2237 #1947
Why this happens: This code is responsible for updatting the padding of near-lying subplots, when a subplot contains sticking out elements (legends, colorbars, guides).
That is, every neighbor subplot updates its padding so the axes spines (plotarea) is aligned within each other. For example,
Look how 1 plot got additional padding so the axes align well.
The code (verbatim) says:
function _update_min_padding!(layout::GridLayout)
map(_update_min_padding!, layout.grid)
layout.minpad = (
maximum(map(leftpad, layout.grid[:,1])),
maximum(map(toppad, layout.grid[1,:])),
maximum(map(rightpad, layout.grid[:,end])),
maximum(map(bottompad, layout.grid[end,:]))
)
end
That is each plot should have maximal padding taken among its neighbors so that each plot has aligned spines (plotarea).
function prepare_output(plt::Plot)
_before_layout_calcs(plt)
w, h = plt.attr[:size]
plt.layout.bbox = BoundingBox(0mm, 0mm, w*px, h*px)
# One pass down and back up the tree to compute the minimum padding
# of the children on the perimeter. This is an backend callback.
_update_min_padding!(plt.layout) # calculate the boxes for each subplot
# now another pass down, to update the bounding boxes
update_child_bboxes!(plt.layout) # update the boxes so that everything aligns well
# the backend callback, to reposition subplots, etc
_update_plot_object(plt)
end
function _update_min_padding!(layout::GridLayout)
map(_update_min_padding!, layout.grid)
layout.minpad = (
maximum(map(leftpad, layout.grid[:,1])),
maximum(map(toppad, layout.grid[1,:])),
maximum(map(rightpad, layout.grid[:,end])),
maximum(map(bottompad, layout.grid[end,:]))
)
end
is that the boxes are only updated for left top bottom right (outer borders)
Boxes inside the grids are not updated. This only aligns tops, bottoms, lefts, rights of a regular (2x2) grid. But it would never align the inside parts like in this example:
Note how p4 is not aligned at all
So the 4th plot left top bounds do update neighbors as recursion never reaches there, simply because grid layout only cares about top left bottom right.
Because, here only top and left needs to be aligned. ( not inside)
Hence, grid layout margins should be aligned from inside too.
One way to this is to have subgrids of grids, so that the same alignment is repeated over each row and each column of the grid. (not only outer borders)
The solution lays in rethinking
function _update_min_padding!(layout::GridLayout)
map(_update_min_padding!, layout.grid)
layout.minpad = (
maximum(map(leftpad, layout.grid[:,1])),
maximum(map(toppad, layout.grid[1,:])),
maximum(map(rightpad, layout.grid[:,end])),
maximum(map(bottompad, layout.grid[end,:]))
)
end
So that maximum also accounts for central alignment, not only sides.
The text was updated successfully, but these errors were encountered:
I was trying to crack why Plots layouting does not always work perfectly and stumbled upon the 2016 year Toms issues and how he had in mind in the first place. I believe not many people to this day understand exactly how layouting works.
Perhaps, it would be a good idea to have comprehensive developer docs http://docs.juliaplots.org/latest/pipeline/ and explain concepts thoroughly with linking relevant code. But this is a digression, better documentation is always desired and all packages.
This is relevant to GR and PyPlot any other backend that would use
_update_min_padding!
callback. Upon conservation with @BeastyBlacksmith I learned that pgfplotsx handles this a little differentlyFirst of all, let us start with an example
This example is a typical MWE when layouting fails:
Note how p4 is not aligned at all

Issues reporting the same things: (perhaps should be deleted to keep things cleaner):
#2237
#1947
Why this happens:
This code is responsible for updatting the padding of near-lying subplots, when a subplot contains sticking out elements (legends, colorbars, guides).
That is, every neighbor subplot updates its padding so the axes spines (plotarea) is aligned within each other. For example,

Look how 1 plot got additional padding so the axes align well.
The code (verbatim) says:
That is each plot should have maximal padding taken among its neighbors so that each plot has aligned spines (plotarea).
Then at the second dive into subplots, margins layout nicely (deleted insets for clarity):
The problem here
is that the boxes are only updated for left top bottom right (outer borders)
Boxes inside the grids are not updated. This only aligns tops, bottoms, lefts, rights of a regular (2x2) grid. But it would never align the inside parts like in this example:
Note how p4 is not aligned at all

So the 4th plot left top bounds do update neighbors as recursion never reaches there, simply because grid layout only cares about top left bottom right.
But it works fine with
Because, here only top and left needs to be aligned. ( not inside)
Hence, grid layout margins should be aligned from inside too.
One way to this is to have subgrids of grids, so that the same alignment is repeated over each row and each column of the grid. (not only outer borders)
The solution lays in rethinking
So that
maximum
also accounts for central alignment, not only sides.The text was updated successfully, but these errors were encountered: