SheffieldML / GPy

Gaussian processes framework in python
BSD 3-Clause "New" or "Revised" License
2.04k stars 562 forks source link

"AttributeError: 'dict' object has no attribute 'figure'" #920

Open flydream0428 opened 3 years ago

flydream0428 commented 3 years ago

When I run the example in the tutorial, (https://nbviewer.jupyter.org/github/SheffieldML/notebook/blob/master/GPy/basic_gp.ipynb), I get the error below. My matplotlib version is 3.3.4


# test
X1 = np.random.uniform(-3.,3.,(20,1))
Y1 = np.sin(X1) + np.random.randn(20,1)*0.05
kernel = GPy.kern.RBF(input_dim=1, variance=1., lengthscale=1.)
m1 = GPy.models.GPRegression(X1,Y1,kernel)
fig = m1.plot()
GPy.plotting.show(fig, filename='basic_gp_regression_notebook')

> AttributeError                            Traceback (most recent call last)
> <ipython-input-61-e67b8a20cbc2> in <module>
>       1 fig = m1.plot()
> ----> 2 GPy.plotting.show(fig, filename='basic_gp_regression_notebook')
> 
> ~\Anaconda3\envs\ml\lib\site-packages\GPy\plotting\__init__.py in show(figure, **kwargs)
>     148     for showing/drawing a figure.
>     149     """
> --> 150     return plotting_library().show_canvas(figure, **kwargs)
>     151 
>     152 
> 
> ~\Anaconda3\envs\ml\lib\site-packages\GPy\plotting\matplot_dep\plot_definitions.py in show_canvas(self, ax, **kwargs)
>      94 
>      95     def show_canvas(self, ax, **kwargs):
> ```
> ---> 96         ax.figure.canvas.draw()
>      97         return ax.figure
>      98 
> 
> AttributeError: 'dict' object has no attribute 'figure'
flydream0428 commented 3 years ago

It works when I remove GPy.plotting.show(fig, filename='basic_gp_regression_notebook')

ekalosak commented 3 years ago

help(GPy.models.GPRegression.plot) shows that this method is defined in GPy/plotting/gpy_plot.py/gp_plots.py. Its return is return pl().add_to_canvas(canvas, plots, legend=legend) where pl().add_to_canvas(...) eventually resolves to GPy/plotting/matplot_dep/plot_definitions.py::add_to_canvas(...). Note that the add_to_canvas returns a dict - namely, the plots kwarg that's passed into it.

So, long story short, you'd think the GPRegression.plot() -> matplotlib.figures.Figure, but actually it's GPRegression.plot() -> Dict[str, matplotlib.figures.Figure]. So your fig variable is a dict, not a Figure.

Fun. This notebook does indeed appear to need to be fixed. Thanks @flydream0428 for reporting ✅

flydream0428 commented 3 years ago

@ekalosak Thanks, I can run the code simply with fig = m.plot(title='basic_gp_regression_notebook_optimized'). I think we can remove the other line.

ekalosak commented 3 years ago

Please let me know if you're able to fix this in a PR, otherwise I'll take a crack at it sometime next week @flydream0428 .

flydream0428 commented 3 years ago

Yes, I will fix this one and the other I have raised. @ekalosak

flydream0428 commented 3 years ago

@ekalosak , Hi Eric, it seems like there are multiple issues with the tutorial notebook. The reported problem in https://github.com/SheffieldML/GPy/issues/379 still exists. Can you have a look? I am not familiar with the Plotly library.

ekalosak commented 3 years ago

Thank you very much for the update @flydream0428. I can see the issue, but I'm not sure how it applies in this context. Do you have an open PR with your fix I can look at? We will be able to identify the specific issue from the CI tests - that will make this process easier.

MDCHAMP commented 2 years ago

Has there been a patch to resolve this issue?

In my environment (GPy=v1.10.0) this issue is still present when calling GPy.plotting.show() from non interactive code (i.e. not a notebook). The workaround suggested above (not calling show()) will not work because no figure will be drawn.

Xiangke-Lan commented 2 years ago

Thx, I have also fixed it as following:


import matplotlib.pyplot as plt

fig = m.plot(title='basic_gp_regression_notebook')
plt.show()
jwwtc commented 2 years ago

Hello.

Has this issue been resolved since it opened? The same error came up to me.

Thanks!