3

I have created several plots in the Jupyter notebook using bqplot. The plots have been arranged using the Jupyter widget HBox and VBox layout attributes. However, I can't work out how to get a tight layout between the rows of subplots. What is the best method of getting a tighter layout?

Below is an example of Python code to run in the Jupyter notebook.

import numpy as np
from bqplot import *
from IPython.display import Javascript, display, clear_output
import ipywidgets as widgets

size = 100
scale = 100.
np.random.seed(0)
x_data = np.arange(size)
y_data = np.cumsum(np.random.randn(size)  * scale)

x_sc = LinearScale()
y_sc = LinearScale()

ax_x = Axis(label='X', scale=x_sc, grid_lines='solid')
ax_y = Axis(label='Y', scale=y_sc, orientation='vertical', grid_lines='solid')

line = Lines(x=x_data, y=x_data, scales={'x': x_sc, 'y': y_sc})

figy=[]
for i in range(2):
    figx=[]
    for j in range(3):
        figx.append(Figure(axes=[ax_x, ax_y], marks=[line], title='Example' + str(i*3+j), fig_margin = dict(top=30, bottom=10, left=20, right=20)))
    figy.append(widgets.HBox(figx)) 
display(widgets.VBox(figy, align_content = 'stretch'))

enter image description here

P-Gn
  • 23,115
  • 9
  • 87
  • 104
DougR
  • 3,196
  • 1
  • 28
  • 29

2 Answers2

3

Here is a solution:

import numpy as np
from bqplot import *
from IPython.display import Javascript, display, clear_output
import ipywidgets as widgets

size = 100
scale = 100.
np.random.seed(0)
x_data = np.arange(size)
y_data = np.cumsum(np.random.randn(size)  * scale)

x_sc = LinearScale()
y_sc = LinearScale()

ax_x = Axis(label='X', scale=x_sc, grid_lines='solid')
ax_y = Axis(label='Y', scale=y_sc, orientation='vertical', grid_lines='solid')

line = Lines(x=x_data, y=x_data, scales={'x': x_sc, 'y': y_sc})

fig_layout = widgets.Layout(width='auto', height='auto')

figy=[]
for i in range(2):
    figx=[]
    for j in range(3):
        figx.append(Figure(layout=fig_layout, axes=[ax_x, ax_y], marks=[line], title='Example' + str(i*3+j), fig_margin = dict(top=30, bottom=10, left=20, right=20)))
    figy.append(widgets.HBox(figx))
display(widgets.VBox(figy, align_content = 'stretch'))

basically overriding the layout attribute of the figure. bqplot figures have a fixed natural height.

enter image description here

Quant
  • 1,593
  • 14
  • 21
  • This definitely controls the layout, but it requires setting margins by hand. It would be great to have an automatic method that would respect axis labels etc. – John Mahoney Sep 16 '20 at 18:05
  • In doing this manual adjustment, it might be useful to add a border. ```fig_layout = widgets.Layout(width='auto', height='auto', border='1px solid Red')``` – John Mahoney Sep 16 '20 at 18:06
0

Each HBox and VBox takes an ipywidgets Layout instance. You can modify the properties of that.

http://ipywidgets.readthedocs.io/en/latest/examples/Widget%20Styling.html

Drew
  • 65
  • 5
  • Yes. I tried the Box widget and tried loads of different settings but I couldn't work it out. I will have another play with it tomorrow. – DougR Jun 21 '17 at 22:11
  • 1
    Try right clicking, hit inspect and play with the box directly in the CSS as a shortcut to figure out the correct configuration. https://css-tricks.com/snippets/css/a-guide-to-flexbox/ – Drew Jun 22 '17 at 23:48
  • Drew, thanks for the tips. However, I still couldn't work it out. I did play with negative margins which can work for a particular configuration. But that method is not consistent when using different layouts (number of subplots, width of jupyter cells etc). I might ask the folks on the ipywidgets gitter channel. – DougR Jun 26 '17 at 09:18