Source code for flyqma.annotation.mixtures.bivariate

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
from scipy.stats import norm, multivariate_normal

from .univariate import UnivariateMixture
from .visualization import BivariateVisualization


[docs]class BivariateMixtureProperties: """ Extension properties for bivariate mixtures. """ @property def supportx(self): """ Support for first dimension. """ return super().support #max_val = np.percentile(self.values[:, 0], q=99.9) #return np.linspace(self.values[:, 0].min(), max_val, num=100) @property def supporty(self): return self.supportx @property def support(self): xx, yy = np.meshgrid(self.supportx, self.supporty) return np.vstack((xx.ravel(), yy.ravel())).T @property def extent(self): """ Extent for x and y axes. """ return np.array([self.lbound, self.ubound, self.ubound, self.lbound]) @property def scale_factor(self): return np.exp(self.support).reshape(self.support_size[0], self.support_size[1], self.dim) @property def support_size(self): return (self.supportx.size, self.supporty.size) @property def components(self): return [multivariate_normal(mean=self.means_[i], cov=self.covariances_[i]) for i in range(self.n_components)]
[docs]class BivariateMixture(BivariateMixtureProperties, BivariateVisualization, UnivariateMixture): """ Bivariate Gaussian mixture model. Inherited attributes: values (array like) - values to which model was fit See sklearn.mixture.GaussianMixture """ dim = 2 def __getitem__(self, margin): """ Returns univariate mixture model for specified <margin>. """ return self.get_marginal_mixture(margin)
[docs] def get_marginal_mixture(self, margin): """ Returns univariate mixture model for specified <margin>. """ values = self.values[:, [margin]] mu = self.means_[:, [margin]] cov = self.covariances_[:, [margin]] weights = self.weights_ args = (mu, cov, weights) kwargs = dict(values=values) return UnivariateMixture.from_parameters(*args, **kwargs)
def get_xmargin(self, log=True): pdf = np.zeros_like(self.supportx) for i in range(self.n_components): pdf += self.get_component_marginal_pdf(i, 0, True) if not log: support = np.exp(self.supportx) pdf /= support else: support = self.supportx return support, pdf def get_ymargin(self, log=True): pdf = np.zeros_like(self.supporty) for i in range(self.n_components): pdf += self.get_component_marginal_pdf(i, 1, True) if not log: support = np.exp(self.supporty) pdf /= support else: support = self.supporty return support, pdf def get_component_marginal_pdf(self, idx, margin, weighted=True): component = self.components[idx] mu = component.mean[margin] sigma = np.sqrt(component.cov[margin, margin]) pdf = norm(mu, sigma).pdf(self.supportx) if weighted: pdf *= self.weights_[idx] return pdf