1
votes

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.

1

1 Answers

1
votes

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