Sum models break the docs
Hey @rhugonnet,
The docs are not compiling anymore and I finally found the time to have a look at that. To me it seems like the the standard plotting routine has an issue, when calling the Variogram.fitted_model through Variogram.transform. It is one of the V.plot(); statements in docs/userguide/variogram.rst.
It started failing after we implemented the sum of models. I can't really tell which of the plot statements causes the error, but we added to that file, so I suspect it is one of the newly added plotting of sum of models.
Here is the traceback of building the docs locally:
>>>-------------------------------------------------------------------------
Exception in /Users/mirko/Library/CloudStorage/Dropbox/python/scikit-gstat/docs/userguide/variogram.rst at block ending on line None
Specify :okexcept: as an option in the ipython:: block to suppress this message
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[129], line 1
----> 1 V.plot();
File ~/Library/CloudStorage/Dropbox/python/scikit-gstat/skgstat/Variogram.py:2966, in Variogram.plot(self, axes, grid, show, hist)
2963 used_backend = plotting.backend()
2965 if used_backend == 'matplotlib':
-> 2966 return plotting.matplotlib_variogram_plot(
2967 self,
2968 axes=axes,
2969 grid=grid,
2970 show=show,
2971 hist=hist
2972 )
2973 elif used_backend == 'plotly':
2974 return plotting.plotly_variogram_plot(
2975 self,
2976 fig=axes,
(...)
2979 hist=hist
2980 )
File ~/Library/CloudStorage/Dropbox/python/scikit-gstat/skgstat/plotting/variogram_plot.py:38, in matplotlib_variogram_plot(variogram, axes, grid, show, hist)
30 def matplotlib_variogram_plot(
31 variogram,
32 axes=None,
(...)
36 ):
37 # get the plotting data
---> 38 x, y, _bins, _exp = __calculate_plot_data(variogram)
40 # do the plotting
41 if axes is None:
File ~/Library/CloudStorage/Dropbox/python/scikit-gstat/skgstat/plotting/variogram_plot.py:18, in __calculate_plot_data(variogram)
15 x = np.linspace(0, np.nanmax(_bins), 100)
17 # apply the model
---> 18 y = variogram.transform(x)
20 # handle the relative experimental variogram
21 if variogram.normalized:
File ~/Library/CloudStorage/Dropbox/python/scikit-gstat/skgstat/Variogram.py:1817, in Variogram.transform(self, x)
1814 self.fit(force=True)
1816 # return the result
-> 1817 return self.fitted_model(x)
File <string>:1, in <lambda>(x)
File ~/Library/CloudStorage/Dropbox/python/scikit-gstat/skgstat/models.py:15, in variogram.<locals>.wrapper(*args, **kwargs)
13 new_args = args[1:]
14 mapping = map(lambda h: func(h, *new_args, **kwargs), args[0])
---> 15 return np.fromiter(mapping, dtype=float)
16 else:
17 return func(*args, **kwargs)
File ~/Library/CloudStorage/Dropbox/python/scikit-gstat/skgstat/models.py:14, in variogram.<locals>.wrapper.<locals>.<lambda>(h)
12 if hasattr(args[0], '__iter__'):
13 new_args = args[1:]
---> 14 mapping = map(lambda h: func(h, *new_args, **kwargs), args[0])
15 return np.fromiter(mapping, dtype=float)
16 else:
File ~/Library/CloudStorage/Dropbox/python/scikit-gstat/skgstat/Variogram.py:1070, in Variogram._build_sum_models.<locals>.sum_models(h, *args)
1068 @models.variogram
1069 def sum_models(h, *args):
-> 1070 return sum(list_models[i](h, *args[args_slices[i]]) for i in range(len(list_models)))
File ~/Library/CloudStorage/Dropbox/python/scikit-gstat/skgstat/Variogram.py:1070, in <genexpr>(.0)
1068 @models.variogram
1069 def sum_models(h, *args):
-> 1070 return sum(list_models[i](h, *args[args_slices[i]]) for i in range(len(list_models)))
TypeError: spherical() missing 1 required positional argument: 'c0'
<<<-------------------------------------------------------------------------
@rhugonnet I am a bit lost here. Do you have any idea, what exactly is going wrong here?
Hi @mmaelicke,
That's strange...
I get the same Sphinx error locally, it is failing at the "Custom model" example V.plot(), but if I run the code of the user guide separately it works (and I had the custom_model.png figure saved locally in savefig/, so it used to pass).
Looking into it in more details...
Here's the code that fails in Sphinx, does it also run for you or am I missing something environment/setup-wise?
import skgstat as skg
import numpy as np
coords, vals = skg.data.pancake(N=200).get('sample')
V = skg.Variogram(
coords,
vals,
n_lags=25
)
V.maxlag = 500
# Build a custom model by applying the @variogram decorator (here adding a linear term to a spherical model)
from skgstat.models import variogram, spherical
@variogram
def custom_model(h, r1, c1, a):
return spherical(h, r1, c1) + h * a
V.model = custom_model
# We define the bounds for r1, c1 and a
bounds_custom = [(0, 0, 0), (np.max(V.bins), np.max(V.experimental), 2)]
V.fit(bounds=bounds_custom)
V.plot()
Looking at the error again (third argument missing in spherical, while three are passed), it looks like the @variogram decorator might be the cause and behaving differently in the ipython code cell than elsewhere (similarly as @savefig that is used to record the figures?).
I don't have much experience with ipython in Sphinx... Do you have any idea how to address this?
I also double-checked and I did add tests for the plotting of custom models, so should in principle always work: https://github.com/mmaelicke/scikit-gstat/blob/main/skgstat/tests/test_variogram.py#L1460
I'll check the code and run the sphinx build in a clean build. Possible, that I also had some images cached...
I will try to free my calendar this week a bit and investigate more into this. A possible fix would be to shift the examples to sphinx_gallery examples, which I implemented way later into the docs (the tutorials are written that way). For the case, that the ipython directive in sphinx was the cause.... We'll see
It seems to be related to this: https://github.com/ipython/ipython/issues/13531 which was fixed in ipython 8.15 or 8.16 and above. But using a clean sphinx install with ipython 8.20, still getting the error...