def generate_plot_lattice_bounds(case, p_vals, x_variable, y_variable, range_x, range_y, resolution):

    V = case.vertices_2D_slice(p_vals, x_variable, y_variable, range_x=range_x, range_y=range_y, log_out=True)
    path = mt.path.Path(V)
    bbox = path.get_extents()
    fraction_x = (bbox.max[0] - bbox.min[0]) / (log10(range_x[1]) - log10(range_x[0]))
    fraction_y = (bbox.max[1] - bbox.min[1]) / (log10(range_y[1]) - log10(range_y[0]))
    resolution_x = int(resolution * fraction_x) + 2
    resolution_y = int(resolution * fraction_y) + 2
    x = np.linspace(bbox.min[0], bbox.max[0], resolution_x)
    y = np.linspace(bbox.min[1], bbox.max[1], resolution_y)
    points = [bbox.min, (bbox.min[0], bbox.max[1]), bbox.max, (bbox.max[0], bbox.min[1])]
    return (points, x, y, path)
def generate_plot_lattice_bounds_new(case, p_vals, x_variable, y_variable, range_x, range_y, resolution):
    
    V = case.vertices_2D_slice(p_vals, x_variable, y_variable, 
                               range_x=range_x, range_y=range_y,
                               log_out=True)
    path=mt.path.Path(V)    
    bbox=path.get_extents()
    ## fraction_x = (bbox.max[0]-bbox.min[0])/(log10(range_x[1])-log10(range_x[0]))
    ## fraction_y = (bbox.max[1]-bbox.min[1])/(log10(range_y[1])-log10(range_y[0]))
    ## resolution_x = int(resolution*fraction_x)+2
    ## resolution_y = int(resolution*fraction_y)+2
    
    x=np.linspace(log10(range_x[0]), log10(range_x[1]), resolution)
    y=np.linspace(log10(range_y[0]), log10(range_y[1]), resolution)
    i= 0
    j = 0
    x_indices = []
    y_indices = []
    for xi in x[:-1]:
        if xi > bbox.min[0]:
            break
        i += 1
    x_indices.append(max(0, i-1))
    for xi in x[i:-1]:
        if xi > bbox.max[0]:
            break
        i += 1    
    x_indices.append(min(len(y), i+1))
    for yi in y[:-1]:
        if yi > bbox.min[1]:
            break
        j += 1
    y_indices.append(max(0, j-1))
    for yi in y[j:-1]:
        if yi > bbox.max[1]:
            break
        j += 1   
    y_indices.append(min(len(y), j+1)) 
         
    return (x_indices,y_indices,path)
def draw_2D_positive_roots(self, ax, p_vals, x_variable, y_variable, range_x, 
                           range_y, color_dict=None, colorbar=True, 
                           resolution=100, cmap=mt.cm.jet,
                           included_cases=None):
    
    if color_dict is None:
        color_dict = dict()
    p_bounds = dict(p_vals)
    p_bounds[x_variable] = range_x
    p_bounds[y_variable] = range_y
    hatched_cases = []
    if included_cases is not None:
        included_cases = [i.case_number for i in self(included_cases)]
        if self.number_of_cases < 1e5:
            valid_cases = self.valid_cases(p_bounds=p_bounds)
            hatched_cases = [i for i in valid_cases if i not in included_cases]
            valid_cases = [i for i in valid_cases if i in included_cases]
        else:
            valid_cases = [i for i in included_cases if self(i).is_valid(p_bounds=p_bounds)]
            valid_nonstrict = []
    else:
        valid_cases = self.valid_cases(p_bounds=p_bounds)
    ssystems = list()
    for case_number in valid_cases:
        case = self(case_number)
        if isinstance(case, CyclicalCase) is True:
            V = case.vertices_2D_slice(p_vals, x_variable, y_variable, 
                                       range_x=[range_x[0]/2, range_x[1]*2],
                                       range_y=[range_y[0]/2, range_y[1]*2],
                                       log_out=True)
            for subcase in V:
                path=mt.path.Path(V[subcase], closed=False) 
                ssystems.append((path, case))
        else:
            V = case.vertices_2D_slice(p_vals, x_variable, y_variable, 
                                       range_x=[range_x[0]/2, range_x[1]*2],
                                       range_y=[range_y[0]/2, range_y[1]*2],
                                       log_out=True)
            path=mt.path.Path(V, closed=False) 
            ssystems.append((path, case.ssystem.remove_algebraic_constraints()))
    x = np.linspace(log10(range_x[0]), log10(range_x[1]), resolution)
    y = np.linspace(log10(range_y[0]), log10(range_y[1]), resolution)
    X, Y = np.meshgrid(x, y)
    Z=np.zeros((len(x), len(y)), dtype=np.int)
    Z = Z - 1
    values = dict()
    params = VariablePool(p_vals)
    for i in xrange(len(y)):
        yi = y[i]
        params[y_variable] = 10**yi
        for j in xrange(len(x)):
            xj = x[j]
            params[x_variable] = 10**xj
            Zj = []
            for path, system in ssystems:
                if path.contains_point((xj, yi)):
                    roots = system.positive_roots(params)
                    if isinstance(roots, dict) is True:
                        for subcase in roots:
                            Zj.append(roots[subcase])
                    else:
                        Zj.append(roots)
            Zj.sort()
            nums = [num for num in Zj]
            if len(nums) == 0:
                continue
            key = str(nums[0])
            for index in xrange(1, len(nums)):
                key += ','+str(nums[index])
            try:
                Z[i,j] = values[key]
            except KeyError:
                Z[i,j] = len(values)
                values[key] = len(values)
    colors = dict()
    for i in values:
        colors[values[i]] = cmap(values[i]/(len(values)))
        if i in color_dict:
            colors[values[i]] = color_dict[i]
    fc = [colors[i] for i in xrange(len(values))]
    cf=ax.contourf(X, Y, Z, cmap=None,
                   levels=[-2, -1] + [i for i in xrange(len(values)+1)],
                   colors = ['k'] + fc + ['k'])
    colors = {key:colors[values[key]] for key in values}
    if colorbar is True:
        c_ax,kw=mt.colorbar.make_axes(ax)
        c_ax.set_aspect(15)
        self.draw_region_colorbar(c_ax, colors)
    ax.set_xlim([log10(min(range_x)), log10(max(range_x))])
    ax.set_ylim([log10(min(range_y)), log10(max(range_y))])
    if x_variable in self._latex:
        x_variable = '$'+self._latex[x_variable]+'$'
    if y_variable in self._latex:
        y_variable = '$'+self._latex[y_variable]+'$'
    ax.set_xlabel(r'$\log_{10}$(' + x_variable + ')')
    ax.set_ylabel(r'$\log_{10}$(' + y_variable + ')')
    return cf, colors
def draw_2D_routh_index(self, ax, p_vals, x_variable, y_variable, range_x, range_y, color_dict=None,
                           colorbar=True, resolution=100, cmap=mt.cm.Spectral_r):
    
    if color_dict is None:
        color_dict = dict()
    p_bounds = dict(p_vals)
    p_bounds[x_variable] = range_x
    p_bounds[y_variable] = range_y
    valid_cases = self.valid_cases(p_bounds=p_bounds)
    ssystems = list()
    for case_number in valid_cases:
        case = self(case_number)
        V = case.vertices_2D_slice(p_vals, x_variable, y_variable, 
                               range_x=[range_x[0]/2, range_x[1]*2], range_y=[range_y[0]/2, range_y[1]*2],
                               log_out=True)
        path=mt.path.Path(V, closed=False) 
        ssystems.append((path, case.ssystem.remove_algebraic_constraints()))
    x = np.linspace(log10(range_x[0]), log10(range_x[1]), resolution)
    y = np.linspace(log10(range_y[0]), log10(range_y[1]), resolution)
    X, Y = np.meshgrid(x, y)
    Z=np.zeros((len(x), len(y)), dtype=np.int)
    values = dict()
    params = VariablePool(p_vals)
    Zj = set()
    for i in xrange(len(y)):
        yi = y[i]
        params[y_variable] = 10**yi
        for j in xrange(len(x)):
            xj = x[j]
            params[x_variable] = 10**xj
            Zj.clear()
            for path, ssystem in ssystems:
                if path.contains_point((xj, yi)):
                    Zj.add(ssystem.routh_index(params))
            nums = [num for num in Zj]
            if len(nums) == 0:
                continue
            key = str(nums[0])
            for index in xrange(1, len(nums)):
                key += ','+str(nums[index])
            try:
                Z[i,j] = values[key]
            except KeyError:
                Z[i,j] = len(values)
                values[key] = len(values)
    colors = dict()
    for i in values:
        colors[values[i]] = cmap(values[i]/(len(values)))
        if i in color_dict:
            colors[values[i]] = color_dict[i]
    fc = [colors[i] for i in xrange(len(values))]
    cf=ax.contourf(X, Y, Z, cmap=None,
                   levels=[-1] + [i for i in xrange(len(values)+1)],
                   colors = fc + ['k'])
    colors = {key:colors[values[key]] for key in values}
    if colorbar is True:
        c_ax,kw=mt.colorbar.make_axes(ax)
        c_ax.set_aspect(15)
        self.draw_region_colorbar(c_ax, colors)
    ax.set_xlim([log10(min(range_x)), log10(max(range_x))])
    ax.set_ylim([log10(min(range_y)), log10(max(range_y))])
    if x_variable in self._latex:
        x_variable = '$'+self._latex[x_variable]+'$'
    if y_variable in self._latex:
        y_variable = '$'+self._latex[y_variable]+'$'
    ax.set_xlabel(r'$\log_{10}$(' + x_variable + ')')
    ax.set_ylabel(r'$\log_{10}$(' + y_variable + ')')
    return cf, colors