I didn’t initially appreciate the role of the zoom in this. match_aspect
(as stated in its docs) only works when auto-ranging is active, and range bounds have not been set by the user. If you explicitly set range bounds, including by panning or zooming, then Bokeh will not override your setting, regardless of what happens to aspect ratios as a result. So I would regard this as behaving as expected. [1]
My statement above concerned resizing the plot without also zooming it, i.e. with auto-ranging still active. In that case, the aspect of the image is preserved even when the plot is resized (and this is accomplished by automatically updating the range bounds as necessary).
I don’t have a good option to suggest if you need to support zooming except to settle for a fixed
sizing mode and not allow the plot to change size. Then the default zoom tool (and also box zoom with match_aspect=True
set) will preserve the original aspect through their operation.
As for why the pixels are not square, it’s because of you have this backwards:
dw=img.shape[0], dh=img.shape[1]
Numpy arrays are row-major by default, so you want the reverse:
dw=img.shape[1], dh=img.shape[0]
With that change (and a fixed sizing mode) the pixels are square, as expected:
Presumably aspect matching would start working again if you added and used a reset tool after a plot resize, because then auto-ranging would resume. ↩︎