question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Updating `GridspecLayout` on click

See original GitHub issue

Hi, thanks to the developers for putting this thing together – it looks awesome!

I have a usage question though. I’m trying to make a layout of plots with NxM rows and columns. Right now I’m prototyping with just buttons. The idea is to be able to expand the layout (i.e. add new panels) by clicking on one of the buttons.

Here’s a class I have so far (probably not the best way, but anyway).

import ipywidgets as ipyW
from IPython.display import display

class PlotGrid():
  def __init__(self, nn):
    self.panels = []
    for n in range(nn):
      self.createNewPanel(n=n)
    self.redraw()
  
  def createNewPanel(self, **kwargs):
    button = ipyW.Button(description='Button {}'.format(kwargs['n']), 
                         layout=ipyW.Layout(height='auto', width='auto'))
    button.on_click(self.appendGrid)
    self.panels.append(button)
    
  def appendGrid(self, status):
    self.createNewPanel(n=len(self.panels))
    self.redraw()
  
  def redraw(self):
    ncols = int(np.sqrt(len(self.panels)))
    nrows = int(np.ceil(len(self.panels) / ncols))
    self.grid = ipyW.GridspecLayout(nrows, ncols)
    n = 0
    for i in range(self.grid.n_rows):
      for j in range(self.grid.n_columns):
        if (n < len(self.panels)):
          self.grid[i, j] = self.panels[n]
        n += 1
  def show(self):
    display(self.grid)

So when I run this:

plotgrid = PlotGrid(12)
plotgrid.show()

it does what it should: fills in the .grid object with panels. When I click on the button the appendGrid function is indeed called, and it does append the new panels to the grid as it should. But for some reason the result is not displayed in the cell: it just remains the same. If I later update the cell by running plotgrid.show() again – it draws the new extended .grid as it should.

So I think I’m not understanding something fundamental with how the display function works and Jupyter handles the events.


These are the versions of the relevant packages I got through conda:

ipykernel                 5.2.0            py38h23f93f0_1    conda-forge
ipython                   7.13.0           py38h32f6830_2    conda-forge
jupyterlab                2.1.0                      py_0    conda-forge
widgetsnbextension        3.5.1                    py38_0    conda-forge

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
ianhicommented, Aug 10, 2020

Hey @haykh your solution is probably the best approach, so congrats on figuring that out! I think the issue was that display doesn’t work quite the way you’d expect. If you change the objects that went into a display they will not immediately update. Instead you need to explicitly update the display (you can get a reference to it by providing an id). Like so:

cell 1:

some_var = 'a'
display_handle = display(some_var, display_id='some-unique-id')
some_var = 'b'

Will have a as the output cell 2:

display_handle.update(some_var)

now cell 1’s output will be b.

You can read more about this here, here and here. I would particularly recommend implementing the _ipython_display_ method on your class.

In your working example you are circumventing having to do something like that by using the widget update system. The Box object listens for changes to it’s children and updates any views of itself whenever it’s children changes. Unfortunately that is the best solution as my example above with update_display doesn’t actually work with ipywidgets, which is a known bug https://github.com/jupyter-widgets/ipywidgets/issues/1180

0reactions
ianhicommented, Aug 10, 2020

i think this enables ipympl backend:

Yup it does!

Your approach is totally reasonable, it’s the “ipywidgets” solution whereas I was suggesting the “matplotlib” solution. More about this in this unmerged PR updating ipympl examples: https://github.com/matplotlib/ipympl/pull/244

I see you’re using display(fig). Beware that display(fig) and display(fig.canvas) are actually pretty different. The former will display a static png, while the latter will create an interactive plot so you can can pan, zoom, and easily update the contents.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Issue with GridspecLayout (Ipywidgets) on Colaboratory
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our ...
Read more >
Dynamically update plot with plotly and ipywidgets
Dynamically update plot with plotly and ipywidgets ... grid = GridspecLayout(1, 5, width='900px', height='150px',grid_gap="10px")grid[0,0] = ...
Read more >
User Guide — Jupyter Widgets 7.7.2 documentation
2x2 Grid · AppLayout · Grid layout · Creating scatter plots using GridspecLayout · Style attributes · Example ... Updating a widget in...
Read more >
ipywidgets: Interactive Widgets in Jupyter Notebooks ...
Updated On : Jul-29,2022 Time Investment : ~45 mins ... 7.7 AppLayout Layout Object; 7.8 GridspecLayout Layout Object; 7.9 "style" attribute for CSS...
Read more >
Customizing Figure Layouts Using GridSpec and ... - Matplotlib
Basic Quickstart Guide; Fine Adjustments to a Gridspec Layout; GridSpec using SubplotSpec; A Complex Nested GridSpec using SubplotSpec.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found