Problem in pca_utils.py plot_widget() function

Every time I run the notebook locally it gives me this error:

NameError Traceback (most recent call last)
File c:\Users\Youssouf El-Gammal\AppData\Local\Programs\Python\Python311\Lib\site-packages\ipywidgets\widgets\interaction.py:239, in interactive.update(self, *args)
237 value = widget.get_interact_value()
238 self.kwargs[widget._kwarg] = value
→ 239 self.result = self.f(**self.kwargs)
240 show_inline_matplotlib_plots()
241 if self.auto_display and self.result is not None:

File c:\Users\Youssouf El-Gammal\Desktop\Machine-Learning-Specialization\C3_Unsupervised Learning_Recommenders_Reinforcement Learning\Week2\PCA_OptionalLab\pca_utils.py:285, in plot_widget..update(angle)
283 def update(angle):
284 ang = angle
→ 285 with fig.batch_update():
286 p0r = rotation_matrix(ang)@p0
287 p1r = rotation_matrix(ang)@p1

NameError: cannot access free variable ‘fig’ where it is not associated with a value in enclosing scope

There is an amazingly detailed explanation of this phenomenon here:

If I understand some of that thread, the way this situation is handled changed in a recent Python release, which may explain why it ran in the Coursera environment but not in yours. Again, if I understand that thread, it only happens if some, eh, creative(?!!) programming practices are in use. You might be able to work around it by tracking how fig is defined, and changing to a mechanism that Python better tolerates.

2 Likes

Your post was over a year ago, so I’m sure you’ve moved on, but here is a solution to get the code working for anyone experiencing the issue in the future. You just have to initialize the 2 figure variables before the definition of the update() function.

Before:
def update(angle):

fig = go.FigureWidget(…)
rhs_fig = go.FigureWidget(…)

Fixed:
fig = go.FigureWidget(…)
rhs_fig = go.FigureWidget(…)
def update(angle):