Smaller range padding for image plot with bokeh
Asked Answered
C

1

2

I'm using bokeh 1.0.4 and I would like to generate an image plot in bokeh using match_aspect=True. Here is a example code for illustration:

from bokeh.models.ranges import DataRange1d
from bokeh.plotting import figure, show
import numpy as np

arr = np.array([[1,2,3],[4,5,6]])

plot = figure(match_aspect=True)
plot.image([arr], x=0, y=0, dw=3, dh=2)

show(plot)

This is what I get: Plot without given ranges

There is a lot empty space around the data, too much for my application, and I would like to have the axes more tight - knowing that this currently cannot perfectly be done, see this other question in section "Update".

So I've tried to use the parameter range_padding, which should be relative to the image dimensions (default unit: percent), but it doesn't work for me, e.g. if I use

from bokeh.models.ranges import DataRange1d
from bokeh.plotting import figure, show
import numpy as np

arr = np.array([[1,2,3],[4,5,6]])

x_range = DataRange1d(range_padding=5, range_padding_units='percent')
y_range = DataRange1d(range_padding=5, range_padding_units='percent')

plot = figure(x_range=x_range, y_range=y_range, match_aspect=True)
plot.image([arr], x=0, y=0, dw=3, dh=2)

show(plot)

the padding is even larger:

Plot using <code>range_padding</code>

Small padding values like 0.05 seem to have no effect. Also I cannot use start and end arguments for the ranges because then the matching aspect ratio is lost. A square in data space should match a square on the screen.

Did I miss something in the way I use the range_padding parameters here? Does anybody have an idea how to reduce the space around the image such that the matching aspect is kept?

Update

I would like not to set plot's height and width to fixed values, because I also want to add a colorbar and maybe other things later and this will increase the plot dimensions in an unpredictable way such that the aspect ratios don't match any more.

Chlorosis answered 18/3, 2019 at 16:22 Comment(0)
S
1

Is this work-around acceptable for you (Bokeh v1.0.4)?

from bokeh.models.ranges import DataRange1d
from bokeh.plotting import figure, show
from bokeh.layouts import Row
from bokeh.palettes import Greys
from bokeh.models import LinearColorMapper, ColorBar
import numpy as np

arr = np.array([[1, 2, 3], [4, 5, 6]])

sx = 3
sy = 2

x_range = DataRange1d(start = 0, end = sx, bounds = (0, sx), range_padding = 5, range_padding_units = 'percent')
y_range = DataRange1d(start = 0, end = sy, bounds = (0, sy), range_padding = 5, range_padding_units = 'percent')

pw = 400
ph = pw * sy / sx
plot = figure(plot_width = pw,
              plot_height = ph,
              x_range = x_range,
              y_range = y_range,
              match_aspect = True)
plot.image([arr], x = 0, y = 0, dw = sx, dh = sy)

color_mapper = LinearColorMapper(palette = Greys[6], low = arr.min(), high = arr.max())
colorbar_plot = figure(plot_height = ph, plot_width = 69, x_axis_location = None, y_axis_location = None, title = None, tools = '', toolbar_location = None)
colorbar = ColorBar(color_mapper = color_mapper, location = (0, 0))
colorbar_plot.add_layout(colorbar, 'left')

show(Row(plot, colorbar_plot))

Result:

enter image description here

Stipulate answered 19/3, 2019 at 11:21 Comment(2)
Thanks again @Tony. Yes, that would work, but forgot to mention in my question, that I'm also needing a colorbar besides the plot and then this will increase the width of the plot and breaks the matching aspect ratio like in my other question. Sorry for not being clear here.Chlorosis
Thanks Tony. In my other question I accepted this workaround. Here, my question is more about the range_padding parameter, which seems to have problems for image plots. It seems to be a bug in bokeh, so I've opened an issue on that. If range_padding would work as expected, I would have a perfect matching aspect ratio, which I have not with this workaround. So I would like to keep the answer open here, until that issue is clarified.Chlorosis

© 2022 - 2024 — McMap. All rights reserved.