code: def generate_X_grid(self, term, n=100, meshgrid=False):
          if not self._is_fitted:
              raise AttributeError('GAM has not been fitted. Call fit first.')
          if self.terms[term].isintercept:
              raise ValueError('cannot create grid for intercept term')
          if self.terms[term].istensor:
              Xs = []
              for term_ in self.terms[term]:
                  Xs.append(np.linspace(term_.edge_knots_[0],
                                        term_.edge_knots_[1],
                                        num=n))
              Xs = np.meshgrid(*Xs, indexing='ij')
              if meshgrid:
                  return tuple(Xs)
              else:
                  return self._flatten_mesh(Xs, term=term)
          elif hasattr(self.terms[term], 'edge_knots_'):
              x = np.linspace(self.terms[term].edge_knots_[0],
                              self.terms[term].edge_knots_[1],
                              num=n)
              if meshgrid:
                  return (x,)
              X = np.zeros((n, self.statistics_['m_features']))
              X[:, self.terms[term].feature] = x
              if getattr(self.terms[term], 'by', None) is not None:
                  X[:, self.terms[term].by] = 1.
              return X
          else:
              raise TypeError('Unexpected term type: {}'.format(self.terms[term]))