예제 #1
0
def validate_color(s):
    "return a valid color arg"
    try:
        if s.lower() == "none":
            return "None"
    except AttributeError:
        pass
    if is_color_like(s):
        return s
    stmp = "#" + s

    if is_color_like(stmp):
        return stmp
    # If it is still valid, it must be a tuple.
    colorarg = s
    msg = ""
    if s.find(",") >= 0:
        # get rid of grouping symbols
        stmp = "".join([c for c in s if c.isdigit() or c == "." or c == ","])
        vals = stmp.split(",")
        if len(vals) != 3:
            msg = "\nColor tuples must be length 3"
        else:
            try:
                colorarg = [float(val) for val in vals]
            except ValueError:
                msg = "\nCould not convert all entries to floats"

    if not msg and is_color_like(colorarg):
        return colorarg

    raise ValueError("%s does not look like a color arg%s" % (s, msg))
예제 #2
0
def validate_color(s):
    'return a valid color arg'
    try:
        if s.lower() == 'none':
            return 'None'
    except AttributeError:
        pass
    if is_color_like(s):
        return s
    stmp = '#' + s
    if is_color_like(stmp):
        return stmp
    # If it is still valid, it must be a tuple.
    colorarg = s
    msg = ''
    if s.find(',') >= 0:
        # get rid of grouping symbols
        stmp = ''.join([c for c in s if c.isdigit() or c == '.' or c == ','])
        vals = stmp.split(',')
        if len(vals) != 3:
            msg = '\nColor tuples must be length 3'
        else:
            try:
                colorarg = [float(val) for val in vals]
            except ValueError:
                msg = '\nCould not convert all entries to floats'

    if not msg and is_color_like(colorarg):
        return colorarg

    raise ValueError('%s does not look like a color arg%s' % (s, msg))
예제 #3
0
 def get(self):
     valuelist = []
     for index, (label, value) in enumerate(self.data):
         field = self.widgets[index]
         if label is None:
             # Separator / Comment
             continue
         elif tuple_to_qfont(value) is not None:
             value = field.get_font()
         elif (isinstance(value, six.string_types)
               or mcolors.is_color_like(value)):
             value = six.text_type(field.text())
         elif isinstance(value, (list, tuple)):
             index = int(field.currentIndex())
             if isinstance(value[0], (list, tuple)):
                 value = value[index][0]
             else:
                 value = value[index]
         elif isinstance(value, bool):
             value = field.checkState() == QtCore.Qt.Checked
         elif isinstance(value, float):
             value = float(str(field.text()))
         elif isinstance(value, int):
             value = int(field.value())
         elif isinstance(value, datetime.datetime):
             value = field.dateTime().toPyDateTime()
         elif isinstance(value, datetime.date):
             value = field.date().toPyDate()
         else:
             value = eval(str(field.text()))
         valuelist.append(value)
     return valuelist
예제 #4
0
    def WaitingtimesDistributions(self,waiting_times,rates,trajectory_index,linestyle,linewidth, marker,colors,title,xlabel,ylabel,is_legend,legend_location):
        """        
        Plots the waiting times for each reaction in the model. 
        Makes use of ObtainWaitingtimes to derive the waiting times out of the SSA output.
   
        Input: 
         - *waiting_times* (dict)
         - *rates* (list)
         - *trajectory_index* (integer)
         - *linestyle* (string)
         - *linewith* (float)    
         - *marker* (string)
         - *colors* (list)
         - *title* (string)
         - *xlabel* (string)
         - *ylabel* (string)
         - *is_legend* (boolean)
         - *legend_location* [default = 'upper right'] (string/integer)
        """
        plt.figure(self.plotnum)               
        if len(rates) == 1:
            j = trajectory_index
        else:
            j=0

        L_legend_names = []
        for r_id in rates:                        
            L_waiting_times = waiting_times[r_id]         # get list of waiting times for a given reaction
            if len(L_waiting_times) > 1:			      # At least 2 waiting times are necessary per reaction
                (x,y,nbins) = LogBin(L_waiting_times,1.5) # Create logarithmic bins (HARDCODED 1.5)
                
                if x != None:
                    if colors == None:              
                        if j >= len(self.colors):                  
                            j=0
                    elif isinstance(colors,list):
                        if j >= len(colors):
                            j=0
                    elif isinstance(colors,str):
                        colors = [colors]
                        j=0              
                    if colors == None:
                        plt.loglog(x,y,marker,ls = linestyle,lw=linewidth,color = self.colors[j])
                    else:
                        if clr.is_color_like(colors[j]):           
                            plt.loglog(x,y,marker,ls = linestyle,lw=linewidth,color = colors[j])
                        else:
                            print("*** WARNING ***: '{0}' is not recognized as a valid color code".format(colors[j]) )
                            plt.loglog(x,y,marker,ls = linestyle,lw=linewidth,color = self.colors[j])
                            colors = None                            
                    L_legend_names.append(r_id)
                    j+=1
        plt.title(title)
        plt.xlabel(xlabel)
        plt.ylabel(ylabel)
        if is_legend:
            plt.legend(L_legend_names,numpoints=1,frameon=True,loc=legend_location)
예제 #5
0
파일: images.py 프로젝트: bobi5rova/cecog
    def draw_merge_contour(self, color, idx=0):
        if is_color_like(color):
            color = hex2color(color)
        color = np.array(color)
        color = np.round(color*np.iinfo(self.dtype).max)
        ix, iy, _ = self.contours[idx]

        # shift contour from subimage to the last column
        xoff = (self._nsub-1-idx)*self.swidth
        self[ix+xoff, iy] = color
예제 #6
0
    def TimeSeries(self,data,npoints,datatype,labels,trajectory_index,linestyle,linewidth,marker,colors,title,xlabel,ylabel,is_legend,legend_location):      
        """        
        Tracks the propensities and/or species over time.

        Input: 
         - *data* (array)
         - *npoints* (integer)
         - *datatype* (list)
         - *labels* (list)
         - *trajectory_index* (integer)
         - *linestyle* (string)
         - *linewidth* (float)
         - *title* (string)
         - *xlabel* (string)
         - *ylabel* (string)
         - *is_legend* (boolean)       
        """
        plt.figure(self.plotnum)       
        datatype_indices = [labels.index(Id) for Id in datatype]
        
        data = getDataForTimeSimPlot(data,npoints,self.quiet)
       
        Arr_time = data[:,0]   
        if len(datatype) == 1:
            j = trajectory_index
        else:
            j=0

        for i in datatype_indices:
            y = data[:,i+1]          
            if colors == None:              
                if j >= len(self.colors):                  
                    j=0
            elif isinstance(colors,list):
                if j >= len(colors):
                    j=0
            elif isinstance(colors,str):
                colors = [colors]
                j=0             

            if colors == None:
                plt.plot(Arr_time,y,marker,ls = linestyle,lw = linewidth,color = self.colors[j])
            else:
                if clr.is_color_like(colors[j]):
                    plt.plot(Arr_time,y,marker,ls = linestyle,lw = linewidth,color = colors[j])
                else:
                    print("*** WARNING ***: '{0}' is not recognized as a valid color code".format(colors[j]) )
                    plt.plot(Arr_time,y,marker,ls = linestyle,lw = linewidth,color = self.colors[j])
                    colors = None
            j+=1
        if is_legend:
            plt.legend(datatype,numpoints=1,frameon=True,loc=legend_location)
        plt.title(title)
        plt.xlabel(xlabel) 
        plt.ylabel(ylabel)      
예제 #7
0
    def AverageTimeSeries(self,means,stds,time,nstd,datatype,labels,linestyle,linewidth,marker,ms,colors,title,xlabel,ylabel,is_legend,legend_location):
        """       
        Plots the average and standard deviation of datatype on a regular grid.

        Input:
         - *means* (array)
         - *stds* (array)
         - *time* (array)
         - *nstd* (float)
         - *datatype* (list)
         - *labels* (list)     
         - *linestyle* (string)
         - *linewidth* (float)
         - *marker* (string)
         - *ms* (float)
         - *colors* (list)       
         - *title* (string)
         - *xlabel* (string)
         - *ylabel* (string)
         - *is_legend* (boolean)
         - *legend_location* [default = 'upper right'] (string/integer)
        """ 
        assert nstd > 0, "Error: The number of STDs must be a value larger than zero"
        plt.figure(self.plotnum)
        datatype_indices = [labels.index(Id) for Id in datatype] 
        j=0
        for i in datatype_indices:
            if colors == None:              
                if j >= len(self.colors):                  
                    j=0
            elif isinstance(colors,list):
                if j >= len(colors):
                    j=0
            elif isinstance(colors,str):
                colors = [colors]
                j=0          
            
            # plot with y-axis error bars
            if colors == None:
                plt.errorbar(time,means[:,i],yerr = nstd*np.array(stds[:,i]),color = self.colors[j],ls = linestyle,lw=linewidth,marker = marker,ms=ms,label = labels[i]) 
            else:
                if clr.is_color_like(colors[j]):     
                    plt.errorbar(time,means[:,i],yerr = nstd*np.array(stds[:,i]),color = colors[j],ls = linestyle,lw=linewidth,marker = marker,ms=ms,label = labels[i])
                else:
                    print("*** WARNING ***: '{0}' is not recognized as a valid color code".format(colors[j]) )
                    plt.errorbar(time,means[:,i],yerr = nstd*np.array(stds[:,i]),color = self.colors[j],ls = linestyle,lw=linewidth,marker = marker,ms=ms,label = labels[i])
                    colors = None
            j+=1
        if is_legend:
            plt.legend(numpoints=1,frameon=True,loc=legend_location)
        plt.title(title)
        plt.xlabel(xlabel)
        plt.ylabel(ylabel)
예제 #8
0
 def Autocorrelations(self,lags,data,datatype,labels,trajectory_index,linestyle,linewidth,marker,colors,title,xlabel,ylabel,is_legend,legend_location):      
     """        
     Input:
      - *lags*
      - *data* (array)      
      - *datatype* (list) 
      - *labels* (list)
      - *trajectory_index* (integer)       
      - *linestyle* (string)
      - *linewidth* (float)
      - *marker* string)
      - *colors* (list)
      - *title* (string)
      - *xlabel* (string)
      - *ylabel* (string)
      - *is_legend* (boolean)
     """
     plt.figure(self.plotnum)
     datatype_indices = [labels.index(Id) for Id in datatype]
     if len(datatype) == 1:
         j = trajectory_index
     else:
         j=0          
     
     for i in datatype_indices:         
         if colors == None:              
             if j >= len(self.colors):                  
                 j=0
         elif isinstance(colors,list):
             if j >= len(colors):
                 j=0
         elif isinstance(colors,str):
             colors = [colors]
             j=0
                                 
         y = data[i][0:len(lags)]          
         if colors == None:
             plt.plot(lags,y,marker,ls = linestyle,lw = linewidth, color = self.colors[j])
         else:   
             if clr.is_color_like(colors[j]):             
                 plt.plot(lags,y,marker,ls = linestyle,lw = linewidth, color = colors[j])
             else:
                 print("*** WARNING ***: '{0}' is not recognized as a valid color code".format(colors[j]) )
                 plt.plot(lags,y,marker,ls = linestyle,lw = linewidth, color = self.colors[j]) 
                 colors = None
         j+=1 
     if is_legend:    
         plt.legend(datatype,numpoints=1,frameon=True,loc=legend_location)      
     plt.title(title)
     plt.xlabel(xlabel) 
     plt.ylabel(ylabel)
예제 #9
0
파일: images.py 프로젝트: bobi5rova/cecog
    def add_contour(self, position, contour, color):
        if is_color_like(color):
            color = hex2color(color)

        if color is None:
            color = hex2color(Colors.white)

        color = np.array(color)
        color = np.round(color*np.iinfo(self.dtype).max)

        # filter pixels that do not lie in the sub image
        contour = np.array(filter(
                lambda c: c[0]<self.swidth and c[1]<self.swidth, contour))
        contour = contour + np.array((position*self.swidth, 0))
        # rgb color according to dtype of the image
        self.contours.append((contour[:, 0], contour[:, 1], color))
예제 #10
0
파일: paga.py 프로젝트: slukassen/scanpy
def _paga_graph(adata,
                ax,
                layout=None,
                layout_kwds={},
                init_pos=None,
                solid_edges=None,
                dashed_edges=None,
                transitions=None,
                threshold=None,
                root=0,
                colors=None,
                labels=None,
                fontsize=None,
                fontweight=None,
                text_kwds=None,
                node_size_scale=1,
                node_size_power=0.5,
                edge_width_scale=1,
                normalize_to_color='reference',
                title=None,
                pos=None,
                cmap=None,
                frameon=True,
                min_edge_width=None,
                max_edge_width=None,
                export_to_gexf=False,
                cax=None,
                colorbar=None,
                use_raw=True,
                cb_kwds={},
                single_component=False,
                arrowsize=30,
                random_state=0):
    node_labels = labels  # rename for clarity
    if (node_labels is not None and isinstance(node_labels, str)
            and node_labels != adata.uns['paga']['groups']):
        raise ValueError(
            'Provide a list of group labels for the PAGA groups {}, not {}.'.
            format(adata.uns['paga']['groups'], node_labels))
    groups_key = adata.uns['paga']['groups']
    if node_labels is None:
        node_labels = adata.obs[groups_key].cat.categories

    if (colors is None or colors == groups_key) and groups_key is not None:
        if (groups_key + '_colors' not in adata.uns
                or len(adata.obs[groups_key].cat.categories) != len(
                    adata.uns[groups_key + '_colors'])):
            utils.add_colors_for_categorical_sample_annotation(
                adata, groups_key)
        colors = adata.uns[groups_key + '_colors']
        for iname, name in enumerate(adata.obs[groups_key].cat.categories):
            if name in settings.categories_to_ignore: colors[iname] = 'grey'

    if isinstance(root, str):
        if root in node_labels:
            root = list(node_labels).index(root)
        else:
            raise ValueError(
                'If `root` is a string, it needs to be one of {} not \'{}\'.'.
                format(node_labels.tolist(), root))
    if isinstance(root, list) and root[0] in node_labels:
        root = [list(node_labels).index(r) for r in root]

    # define the adjacency matrices
    adjacency_solid = adata.uns['paga'][solid_edges].copy()
    if threshold is None:
        threshold = 0.01  # default threshold
    if threshold > 0:
        adjacency_solid.data[adjacency_solid.data < threshold] = 0
        adjacency_solid.eliminate_zeros()
    nx_g_solid = nx.Graph(adjacency_solid)
    if dashed_edges is not None:
        adjacency_dashed = adata.uns['paga'][dashed_edges].copy()
        if threshold > 0:
            adjacency_dashed.data[adjacency_dashed.data < threshold] = 0
            adjacency_dashed.eliminate_zeros()
        nx_g_dashed = nx.Graph(adjacency_dashed)

    # uniform color
    if isinstance(colors, str) and is_color_like(colors):
        colors = [colors for c in range(len(node_labels))]

    # color degree of the graph
    if isinstance(colors, str) and colors.startswith('degree'):
        # see also tools.paga.paga_degrees
        if colors == 'degree_dashed':
            colors = [d for _, d in nx_g_dashed.degree(weight='weight')]
        elif colors == 'degree_solid':
            colors = [d for _, d in nx_g_solid.degree(weight='weight')]
        else:
            raise ValueError(
                '`degree` either "degree_dashed" or "degree_solid".')
        colors = (np.array(colors) - np.min(colors)) / (np.max(colors) -
                                                        np.min(colors))

    # plot gene expression
    var_names = adata.var_names if adata.raw is None else adata.raw.var_names
    if isinstance(colors, str) and colors in var_names:
        x_color = []
        cats = adata.obs[groups_key].cat.categories
        for icat, cat in enumerate(cats):
            subset = (cat == adata.obs[groups_key]).values
            if adata.raw is not None and use_raw:
                adata_gene = adata.raw[:, colors]
            else:
                adata_gene = adata[:, colors]
            x_color.append(np.mean(adata_gene.X[subset]))
        colors = x_color

    # plot continuous annotation
    if (isinstance(colors, str) and colors in adata.obs
            and not is_categorical_dtype(adata.obs[colors])):
        x_color = []
        cats = adata.obs[groups_key].cat.categories
        for icat, cat in enumerate(cats):
            subset = (cat == adata.obs[groups_key]).values
            x_color.append(adata.obs.loc[subset, colors].mean())
        colors = x_color

    # plot categorical annotation
    if (isinstance(colors, str) and colors in adata.obs
            and is_categorical_dtype(adata.obs[colors])):
        from ... import utils as sc_utils
        asso_names, asso_matrix = sc_utils.compute_association_matrix_of_groups(
            adata,
            prediction=groups_key,
            reference=colors,
            normalization='reference' if normalize_to_color else 'prediction')
        utils.add_colors_for_categorical_sample_annotation(adata, colors)
        asso_colors = sc_utils.get_associated_colors_of_groups(
            adata.uns[colors + '_colors'], asso_matrix)
        colors = asso_colors

    if len(colors) < len(node_labels):
        print(node_labels, colors)
        raise ValueError(
            '`color` list need to be at least as long as `groups`/`node_labels` list.'
        )

    # count number of connected components
    n_components, labels = scipy.sparse.csgraph.connected_components(
        adjacency_solid)
    if n_components > 1 and not single_component:
        logg.msg(
            'Graph has more than a single connected component. '
            'To restrict to this component, pass `single_component=True`.')
    if n_components > 1 and single_component:
        component_sizes = np.bincount(labels)
        largest_component = np.where(
            component_sizes == component_sizes.max())[0][0]
        adjacency_solid = adjacency_solid.tocsr()[labels ==
                                                  largest_component, :]
        adjacency_solid = adjacency_solid.tocsc()[:,
                                                  labels == largest_component]
        colors = np.array(colors)[labels == largest_component]
        node_labels = np.array(node_labels)[labels == largest_component]
        logg.info(
            'Restricting graph to largest connected component by dropping categories\n'
            '{}'.format(adata.obs[groups_key].cat.categories[
                labels != largest_component].tolist()))
        nx_g_solid = nx.Graph(adjacency_solid)
        if dashed_edges is not None:
            raise ValueError(
                '`single_component` only if `dashed_edges` is `None`.')

    # node positions from adjacency_solid
    if pos is None:
        if layout is None:
            layout = 'fr'
        if layout == 'fa':
            try:
                from fa2 import ForceAtlas2
            except:
                logg.warn(
                    'Package \'fa2\' is not installed, falling back to layout \'fr\'.'
                    'To use the faster and better ForceAtlas2 layout, '
                    'install package \'fa2\' (`pip install fa2`).')
                layout = 'fr'
        if layout == 'fa':
            np.random.seed(random_state)
            if init_pos is None:
                init_coords = np.random.random((adjacency_solid.shape[0], 2))
            else:
                init_coords = init_pos.copy()
            forceatlas2 = ForceAtlas2(
                # Behavior alternatives
                outboundAttractionDistribution=False,  # Dissuade hubs
                linLogMode=False,  # NOT IMPLEMENTED
                adjustSizes=False,  # Prevent overlap (NOT IMPLEMENTED)
                edgeWeightInfluence=1.0,
                # Performance
                jitterTolerance=1.0,  # Tolerance
                barnesHutOptimize=True,
                barnesHutTheta=1.2,
                multiThreaded=False,  # NOT IMPLEMENTED
                # Tuning
                scalingRatio=2.0,
                strongGravityMode=False,
                gravity=1.0,
                # Log
                verbose=False)
            if 'maxiter' in layout_kwds:
                iterations = layout_kwds['maxiter']
            elif 'iterations' in layout_kwds:
                iterations = layout_kwds['iterations']
            else:
                iterations = 500
            pos_list = forceatlas2.forceatlas2(adjacency_solid,
                                               pos=init_coords,
                                               iterations=iterations)
            pos = {n: [p[0], -p[1]] for n, p in enumerate(pos_list)}
        elif layout == 'eq_tree':
            nx_g_tree = nx_g_solid
            if solid_edges == 'connectivities':
                adj_tree = adata.uns['paga']['connectivities_tree']
                nx_g_tree = nx.Graph(adj_tree)
            pos = utils.hierarchy_pos(nx_g_tree, root)
            if len(pos) < adjacency_solid.shape[0]:
                raise ValueError('This is a forest and not a single tree. '
                                 'Try another `layout`, e.g., {\'fr\'}.')
        else:
            # igraph layouts
            from ... import utils as sc_utils
            g = sc_utils.get_igraph_from_adjacency(adjacency_solid)
            if 'rt' in layout:
                g_tree = g
                if solid_edges == 'connectivities':
                    adj_tree = adata.uns['paga']['connectivities_tree']
                    g_tree = sc_utils.get_igraph_from_adjacency(adj_tree)
                pos_list = g_tree.layout(
                    layout,
                    root=root if isinstance(root, list) else [root]).coords
            elif layout == 'circle':
                pos_list = g.layout(layout).coords
            else:
                # I don't know why this is necessary
                np.random.seed(random_state)
                if init_pos is None:
                    init_coords = np.random.random(
                        (adjacency_solid.shape[0], 2)).tolist()
                else:
                    init_pos = init_pos.copy()
                    # this is a super-weird hack that is necessary as igraphs layout function
                    # seems to do some strange stuff, here
                    init_pos[:, 1] *= -1
                    init_coords = init_pos.tolist()
                try:
                    pos_list = g.layout(layout,
                                        seed=init_coords,
                                        weights='weight',
                                        **layout_kwds).coords
                except:  # hack for excepting attribute error for empty graphs...
                    pos_list = g.layout(layout,
                                        seed=init_coords,
                                        **layout_kwds).coords
            pos = {n: [p[0], -p[1]] for n, p in enumerate(pos_list)}
        pos_array = np.array([pos[n] for count, n in enumerate(nx_g_solid)])
    else:
        if isinstance(pos, str):
            if not pos.endswith('.gdf'):
                raise ValueError(
                    'Currently only supporting reading positions from .gdf files.'
                    'Consider generating them using, for instance, Gephi.')
            s = ''  # read the node definition from the file
            with open(pos) as f:
                f.readline()
                for line in f:
                    if line.startswith('edgedef>'):
                        break
                    s += line
            from io import StringIO
            df = pd.read_csv(StringIO(s), header=-1)
            pos = df[[4, 5]].values
        pos_array = pos
        # convert to dictionary
        pos = {n: [p[0], p[1]] for n, p in enumerate(pos)}

    if len(pos) == 1: pos[0] = (0.5, 0.5)

    # edge widths
    base_edge_width = edge_width_scale * 5 * rcParams['lines.linewidth']

    # draw dashed edges
    if dashed_edges is not None:
        widths = [x[-1]['weight'] for x in nx_g_dashed.edges(data=True)]
        widths = base_edge_width * np.array(widths)
        if max_edge_width is not None:
            widths = np.clip(widths, None, max_edge_width)
        nx.draw_networkx_edges(nx_g_dashed,
                               pos,
                               ax=ax,
                               width=widths,
                               edge_color='grey',
                               style='dashed',
                               alpha=0.5)

    # draw solid edges
    if transitions is None:
        widths = [x[-1]['weight'] for x in nx_g_solid.edges(data=True)]
        widths = base_edge_width * np.array(widths)
        if min_edge_width is not None or max_edge_width is not None:
            widths = np.clip(widths, min_edge_width, max_edge_width)
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            nx.draw_networkx_edges(nx_g_solid,
                                   pos,
                                   ax=ax,
                                   width=widths,
                                   edge_color='black')
    # draw directed edges
    else:
        adjacency_transitions = adata.uns['paga'][transitions].copy()
        if threshold is None: threshold = 0.01
        adjacency_transitions.data[adjacency_transitions.data < threshold] = 0
        adjacency_transitions.eliminate_zeros()
        g_dir = nx.DiGraph(adjacency_transitions.T)
        widths = [x[-1]['weight'] for x in g_dir.edges(data=True)]
        widths = base_edge_width * np.array(widths)
        if min_edge_width is not None or max_edge_width is not None:
            widths = np.clip(widths, min_edge_width, max_edge_width)
        nx.draw_networkx_edges(g_dir,
                               pos,
                               ax=ax,
                               width=widths,
                               edge_color='black',
                               arrowsize=arrowsize)

    if export_to_gexf:
        if isinstance(colors[0], tuple):
            from matplotlib.colors import rgb2hex
            colors = [rgb2hex(c) for c in colors]
        for count, n in enumerate(nx_g_solid.nodes()):
            nx_g_solid.node[count]['label'] = str(node_labels[count])
            nx_g_solid.node[count]['color'] = str(colors[count])
            nx_g_solid.node[count]['viz'] = {
                'position': {
                    'x': 1000 * pos[count][0],
                    'y': 1000 * pos[count][1],
                    'z': 0
                }
            }
        filename = settings.writedir + 'paga_graph.gexf'
        logg.msg('exporting to {}'.format(filename), v=1)
        if settings.writedir != '' and not os.path.exists(settings.writedir):
            os.makedirs(settings.writedir)
        nx.write_gexf(nx_g_solid, settings.writedir + 'paga_graph.gexf')

    ax.set_frame_on(frameon)
    ax.set_xticks([])
    ax.set_yticks([])

    # groups sizes
    if (groups_key is not None and groups_key + '_sizes' in adata.uns):
        groups_sizes = adata.uns[groups_key + '_sizes']
    else:
        groups_sizes = np.ones(len(node_labels))
    base_scale_scatter = 2000
    base_pie_size = (base_scale_scatter /
                     (np.sqrt(adjacency_solid.shape[0]) + 10) *
                     node_size_scale)
    median_group_size = np.median(groups_sizes)
    groups_sizes = base_pie_size * np.power(groups_sizes / median_group_size,
                                            node_size_power)

    if fontsize is None:
        fontsize = rcParams['legend.fontsize']

    # usual scatter plot
    if not isinstance(colors[0], dict):
        sct = ax.scatter(pos_array[:, 0],
                         pos_array[:, 1],
                         c=colors,
                         edgecolors='face',
                         s=groups_sizes,
                         cmap=cmap)
        for count, group in enumerate(node_labels):
            ax.text(pos_array[count, 0],
                    pos_array[count, 1],
                    group,
                    verticalalignment='center',
                    horizontalalignment='center',
                    size=fontsize,
                    fontweight=fontweight,
                    **text_kwds)
    # else pie chart plot
    else:
        # start with this dummy plot... otherwise strange behavior
        sct = ax.scatter(pos_array[:, 0],
                         pos_array[:, 1],
                         c='white',
                         edgecolors='face',
                         s=groups_sizes,
                         cmap=cmap)
        trans = ax.transData.transform
        bbox = ax.get_position().get_points()
        ax_x_min = bbox[0, 0]
        ax_x_max = bbox[1, 0]
        ax_y_min = bbox[0, 1]
        ax_y_max = bbox[1, 1]
        ax_len_x = ax_x_max - ax_x_min
        ax_len_y = ax_y_max - ax_y_min
        trans2 = ax.transAxes.inverted().transform
        pie_axs = []
        for count, n in enumerate(nx_g_solid.nodes()):
            pie_size = groups_sizes[count] / base_scale_scatter
            x1, y1 = trans(pos[n])  # data coordinates
            xa, ya = trans2((x1, y1))  # axis coordinates
            xa = ax_x_min + (xa - pie_size / 2) * ax_len_x
            ya = ax_y_min + (ya - pie_size / 2) * ax_len_y
            # clip, the fruchterman layout sometimes places below figure
            if ya < 0: ya = 0
            if xa < 0: xa = 0
            pie_axs.append(
                pl.axes([xa, ya, pie_size * ax_len_x, pie_size * ax_len_y],
                        frameon=False))
            pie_axs[count].set_xticks([])
            pie_axs[count].set_yticks([])
            if not isinstance(colors[count], dict):
                raise ValueError(
                    '{} is neither a dict of valid matplotlib colors '
                    'nor a valid matplotlib color.'.format(colors[count]))
            color_single = colors[count].keys()
            fracs = [colors[count][c] for c in color_single]
            if sum(fracs) < 1:
                color_single = list(color_single)
                color_single.append('grey')
                fracs.append(1 - sum(fracs))
            pie_axs[count].pie(fracs, colors=color_single)
        if node_labels is not None:
            for ia, a in enumerate(pie_axs):
                a.text(0.5,
                       0.5,
                       node_labels[ia],
                       verticalalignment='center',
                       horizontalalignment='center',
                       transform=a.transAxes,
                       size=fontsize,
                       fontweight=fontweight,
                       **text_kwds)
    return pos_array, sct
예제 #11
0
파일: plot.py 프로젝트: benhills/ImpDAR
def plot_picks(rd, xd, yd, colors=None, flatten_layer=None, fig=None, ax=None, just_middle=False, picknums=None, **plotting_kwargs):
    """Update the plotting of the current pick.

    Parameters
    ----------
    colors: str
        You have choices here. This can be a npicksx3 list, an npicks list of
        3-letter strings, a 3 letter string, a single string, or a npicks list.
        Any of the x3 options are interpretted as top, middle, bottom colors.
        If it is a string, the lines are all plotted in this color. If it is
        a list, the different values are used for the different lines.
    flatten_layer: int, optional
        Make this layer flat in the plot. Distorts all layers. Default is no
        distortion.
    """
    if ax is None:
        if fig is not None:
            ax = plt.gca()
        else:
            fig, ax = plt.subplots()

    # just do nothing if we have no picks
    if rd.picks is None or rd.picks.samp1 is None:
        return fig, ax

    offset, mask = get_offset(rd, flatten_layer)

    if picknums is None:
        if rd.picks.picknums is None:
            return fig, ax
        picknums = rd.picks.picknums

    variable_colors = False
    if not colors:  # may be False or None
        cl = 'mgm'
    else:
        if type(colors) == str:
            if len(colors) == 3:
                cl = colors
            else:
                cl = ('none', colors, 'none')
        elif (type(colors) == bool) and colors:
            colors = (COLORS_NONGRAY * (rd.picks.samp1.shape[0] // len(COLORS_NONGRAY) + 1))[:len(picknums)]
            variable_colors = True
        elif not len(colors) == len(picknums):
            if (len(colors) == 3) and not just_middle:
                cl = colors
            else:
                raise ValueError('If not a string, must have length 3 or length npicks')
        else:
            variable_colors = True

    for j, pn in enumerate(picknums):
        # use i and j so that we can color out of order
        i = rd.picks.picknums.index(pn)
        if variable_colors:
            if hasattr(colors[j], '__len__') and len(colors[j]) == 3 and not just_middle:
                cl = colors[j]
            elif is_color_like(colors[j]):
                cl = ('none', colors[j], 'none')
            else:
                raise ValueError('Color ', colors[j], ' not defined')
        c = np.zeros(xd.shape)
        c[:] = np.nan
        comb_mask = np.logical_or(mask, np.isnan(rd.picks.samp2[i, :]))
        c[~comb_mask] = yd[(rd.picks.samp2[i, :] + offset)[~comb_mask].astype(int)]
        t = np.zeros(xd.shape)
        t[:] = np.nan
        t[~comb_mask] = yd[(rd.picks.samp1[i, :] + offset)[~comb_mask].astype(int)]
        b = np.zeros(xd.shape)
        b[:] = np.nan
        b[~comb_mask] = yd[(rd.picks.samp3[i, :] + offset)[~comb_mask].astype(int)]
        ax.plot(xd, c, color=cl[1], **plotting_kwargs)
        ax.plot(xd, t, color=cl[0], **plotting_kwargs)
        ax.plot(xd, b, color=cl[2], **plotting_kwargs)
    return fig, ax
예제 #12
0
def add_rectangles(ax,d):
    """
    Adds one or more rectangles to Axis ax using the parameters in dictionary d.
    """
    # Handle inputs
    assert isinstance(ax,Axes)
    # lims
    assert('lims' in d.keys())
    lims = d['lims']
    if isinstance(lims,tuple):
        assert(len(lims)==4)
        lims = [lims]
    assert(isinstance(lims,list))
    N = len(lims)
    assert(all([isinstance(t,tuple) for t in lims]))
    assert(all([len(t)==4 for t in lims]))
    # color
    color = d['color'] if 'color' in d.keys() else 'r'
    if isinstance(color,list):
        assert(len(color)==N)
        assert(all([is_color_like(c) for c in color]))
    else:
        assert is_color_like(color)
        color = [color for i in range(N)]
    # fill
    fill = d['fill'] if 'fill' in d.keys() else False
    if isinstance(fill,bool):
        fill = [fill for i in range(N)]
    else:
        assert(isinstance(fill,list))
        assert(len(fill)==N)
        assert(all([isinstance(f,bool) for f in fill]))
    # alpha
    alpha = d['alpha'] if 'alpha' in d.keys() else 1
    if isinstance(alpha,(float,int,np.float)):
        alpha = [alpha for i in range(N)]
    else:
        assert(isinstance(alpha,list))
        assert(len(alpha)==N)
        assert(all([isinstance(a,(float,int,np.float)) for a in alpha]))
    # linewidth
    linewidth = d['linewidth'] if 'linewidth' in d.keys() else 2
    if isinstance(linewidth,(float,int,np.float)):
        linewidth = [linewidth for i in range(N)]
    else:
        assert(isinstance(linewidth,list))
        assert(len(linewidth)==N)
        assert(all([isinstance(lw,(float,int,np.float)) for lw in linewidth]))
    # additional parameters
    kws = [k for k in d.keys() if k not in ('lims','color','fill','alpha','linewidth')]
    kwargs = dict()
    for k in kws:
        kwargs[k] = d[k]

    # add the rectangles
    for i in range(N):
        l,c,f,a,lw = lims[i],color[i],fill[i],alpha[i],linewidth[i]
        rect = Rectangle((l[2]-0.5,l[0]-0.5),l[3]-l[2],l[1]-l[0],color=c,fill=f,
                          alpha=a,linewidth=lw,**kwargs)
        ax.add_patch(rect)

    return
예제 #13
0
def add_circles(ax,d):
    """
    adds one or more circles to axis ax using the parameters in dictionary d.
    """
    # handle inputs
    assert isinstance(ax,Axes)
    # center
    assert('center' in d.keys())
    center = d['center']
    if isinstance(center,tuple):
        assert(len(center)==2)
        center = [center]
    assert(isinstance(center,list))
    N = len(center)
    assert(all([isinstance(x,tuple) for x in center]))
    assert(all([len(x)==2 for x in center]))
    # radius
    assert('R' in d.keys())
    R = d['R']
    if isinstance(R,Number):
        R = [R for i in range(N)]
    assert(isinstance(R,list))
    assert(len(R)==N)
    assert(all([isinstance(i,Number) for i in R]))
    # color
    color = d['color'] if 'color' in d.keys() else 'r'
    if isinstance(color,list):
        assert(len(color)==N)
        assert(all([is_color_like(c) for c in color]))
    else:
        assert is_color_like(color)
        color = [color for i in range(N)]
    # fill
    fill = d['fill'] if 'fill' in d.keys() else False
    if isinstance(fill,bool):
        fill = [fill for i in range(N)]
    else:
        assert(isinstance(fill,list))
        assert(len(fill)==N)
        assert(all([isinstance(f,bool) for f in fill]))
    # alpha
    alpha = d['alpha'] if 'alpha' in d.keys() else 1
    if isinstance(alpha,(float,int,np.float)):
        alpha = [alpha for i in range(N)]
    else:
        assert(isinstance(alpha,list))
        assert(len(alpha)==N)
        assert(all([isinstance(a,(float,int,np.float)) for a in alpha]))
    # linewidth
    linewidth = d['linewidth'] if 'linewidth' in d.keys() else 2
    if isinstance(linewidth,(float,int,np.float)):
        linewidth = [linewidth for i in range(N)]
    else:
        assert(isinstance(linewidth,list))
        assert(len(linewidth)==N)
        assert(all([isinstance(lw,(float,int,np.float)) for lw in linewidth]))
    # additional parameters
    kws = [k for k in d.keys() if k not in ('center','R','color','fill','alpha','linewidth')]
    kwargs = dict()
    for k in kws:
        kwargs[k] = d[k]

    # add the circles
    for i in range(N):
        cent,r,col,f,a,lw = center[i],R[i],color[i],fill[i],alpha[i],linewidth[i]
        circ = Circle((cent[1],cent[0]),r,color=col,fill=f,alpha=a,linewidth=lw,**kwargs)
        ax.add_patch(circ)

    return
예제 #14
0
def add_scalebar(ax,d):
    """
    Adds an overlaid scalebar to an image, using the parameters in dict d.

    The dictionary d has required and optional parameters as follows:
        Nx,Ny           (req'd) the image extent
        space           (str) 'Q' or 'R'
        length          (number) the scalebar length
        width           (number) the scalebar width
        pixelsize       (number)
        pixelunits      (str)
        color           (color)
        label           (bool)
        labelsize       (number)
        labelcolor      (color)
        alpha           (number)
        position        (str) 'ul','ur','bl', or 'br' for the
                        upperleft, upperright, bottomleft, bottomright
        ticks           (bool) if False, turns off image border ticks
    """
    # handle inputs
    assert isinstance(ax,Axes)
    # image extent
    assert('Nx' in d.keys())
    assert('Ny' in d.keys())
    Nx,Ny = d['Nx'],d['Ny']
    # real or diffraction
    space = d['space'] if 'space' in d.keys() else 'Q'
    assert(space in ('Q','R'))
    # length,width
    length = d['length'] if 'length' in d.keys() else None
    width = d['width'] if 'width' in d.keys() else 6
    # pixelsize, pixelunits
    pixelsize = d['pixelsize'] if 'pixelsize' in d.keys() else 1
    pixelunits = d['pixelunits'] if 'pixelunits' in d.keys() else 'pixels'
    # color
    color = d['color'] if 'color' in d.keys() else 'w'
    assert is_color_like(color)
    # labels
    label = d['label'] if 'label' in d.keys() else True
    labelsize = d['labelsize'] if 'labelsize' in d.keys() else 16
    labelcolor = d['labelcolor'] if 'labelcolor' in d.keys() else color
    assert isinstance(label,bool)
    assert isinstance(labelsize,Number)
    assert is_color_like(labelcolor)
    # alpha
    alpha = d['alpha'] if 'alpha' in d.keys() else 1
    assert isinstance(alpha,(Number))
    # position
    position = d['position'] if 'position' in d.keys() else 'br'
    assert position in ('ul','ur','bl','br')
    # ticks
    ticks = d['ticks'] if 'ticks' in d.keys() else False
    assert isinstance(ticks,bool)
    # additional parameters
    kws = [k for k in d.keys() if k not in ('Nx','Ny','length',
                       'width','pixelsize','pixelunits','color','label',
                       'labelsize','labelcolor','alpha','position','ticks')]
    kwargs = dict()
    for k in kws:
        kwargs[k] = d[k]

    # Get length
    if length is None:
        length_units,length_pixels,_ = get_nice_spacing(Nx,Ny,pixelsize)
    else:
        length_units,length_pixels = length,length/pixelsize

    # Get position
    if position == 'ul':
        x0,y0 = 0,0
        xshiftdir,yshiftdir = 1,1
    elif position == 'ur':
        x0,y0 = 0,Ny-1
        xshiftdir,yshiftdir = 1,-1
    elif position == 'bl':
        x0,y0 = Nx-1,0
        xshiftdir,yshiftdir = -1,1
    else:
        x0,y0 = Nx-1,Ny-1
        xshiftdir,yshiftdir = -1,-1
    pad = 0.2*length_pixels
    xshift = xshiftdir * pad
    yshift = yshiftdir * (length_pixels/2.+pad)
    x0 = x0 + xshift
    y0 = y0 + yshift
    xi,yi = x0,y0-length_pixels/2.
    xf,yf = x0,y0+length_pixels/2.
    labelpos_x = x0 + pad*xshiftdir/2.
    labelpos_y = y0

    # Add line
    ax.plot((yi,yf),(xi,xf),lw=width,color=color,alpha=alpha)

    # Add label
    if label:
        labeltext = str(length_units)+' '+pixelunits
        if xshiftdir>0: va='top'
        else: va='bottom'
        ax.text(labelpos_y,labelpos_x,labeltext,size=labelsize,
                color=labelcolor,alpha=alpha,ha='center',va=va)

    if not ticks:
        ax.set_xticks([])
        ax.set_yticks([])
    return
예제 #15
0
def _valid_plot_kwargs():
    '''
    Construct and return the "valid kwargs table" for the mplfinance.plot() function.
    A valid kwargs table is a `dict` of `dict`s.  The keys of the outer dict are the
    valid key-words for the function.  The value for each key is a dict containing
    2 specific keys: "Default", and "Validator" with the following values:
        "Default"      - The default value for the kwarg if none is specified.
        "Validator"    - A function that takes the caller specified value for the kwarg,
                         and validates that it is the correct type, and (for kwargs with 
                         a limited set of allowed values) may also validate that the
                         kwarg value is one of the allowed values.
    '''

    vkwargs = {
        'columns': {
            'Default': ('Open', 'High', 'Low', 'Close', 'Volume'),
            'Validator':
            lambda value: isinstance(value, (tuple, list)) and len(value) == 5
            and all(isinstance(c, str) for c in value)
        },
        'type': {
            'Default':
            'ohlc',
            'Validator':
            lambda value: value in ('candle', 'candlestick', 'ohlc',
                                    'ohlc_bars', 'line', 'renko', 'pnf')
        },
        'style': {
            'Default':
            'default',
            'Validator':
            lambda value: value in _styles.available_styles() or isinstance(
                value, dict)
        },
        'volume': {
            'Default': False,
            'Validator': lambda value: isinstance(value, bool)
        },
        'mav': {
            'Default': None,
            'Validator': _mav_validator
        },
        'renko_params': {
            'Default': dict(),
            'Validator': lambda value: isinstance(value, dict)
        },
        'pnf_params': {
            'Default': dict(),
            'Validator': lambda value: isinstance(value, dict)
        },
        'study': {
            'Default': None,
            'Validator': lambda value: _kwarg_not_implemented(value)
        },
        'marketcolors': {
            'Default': None,  # use 'style' for default, instead.
            'Validator': lambda value: isinstance(value, dict)
        },
        'no_xgaps': {
            'Default': True,  # None means follow default logic below:
            'Validator': lambda value: _warn_no_xgaps_deprecated(value)
        },
        'show_nontrading': {
            'Default': False,
            'Validator': lambda value: isinstance(value, bool)
        },
        'figscale': {
            'Default':
            1.0,  # scale base figure size up or down.
            'Validator':
            lambda value: isinstance(value, float) or isinstance(value, int)
        },
        'figratio': {
            'Default':
            DEFAULT_FIGRATIO,  # aspect ratio; scaled to 8.0 height
            'Validator':
            lambda value: isinstance(value,
                                     (tuple, list)) and len(value) == 2 and
            isinstance(value[0],
                       (float, int)) and isinstance(value[1], (float, int))
        },
        'figsize': {
            'Default':
            None,  # figure size; overrides figratio and figscale
            'Validator':
            lambda value: isinstance(value,
                                     (tuple, list)) and len(value) == 2 and
            isinstance(value[0],
                       (float, int)) and isinstance(value[1], (float, int))
        },
        'linecolor': {
            'Default': None,  # line color in line plot
            'Validator': lambda value: mcolors.is_color_like(value)
        },
        'title': {
            'Default': None,  # Plot Title
            'Validator': lambda value: isinstance(value, str)
        },
        'ylabel': {
            'Default': 'Price',  # y-axis label
            'Validator': lambda value: isinstance(value, str)
        },
        'ylabel_lower': {
            'Default': None,  # y-axis label default logic below
            'Validator': lambda value: isinstance(value, str)
        },
        'addplot': {
            'Default':
            None,
            'Validator':
            lambda value: isinstance(value, dict) or (isinstance(
                value, list) and all([isinstance(d, dict) for d in value]))
        },
        'savefig': {
            'Default':
            None,
            'Validator':
            lambda value: isinstance(value, dict) or isinstance(value, str) or
            isinstance(value, io.BytesIO)
        },
        'block': {
            'Default': True,
            'Validator': lambda value: isinstance(value, bool)
        },
        'returnfig': {
            'Default': False,
            'Validator': lambda value: isinstance(value, bool)
        },
        'return_calculated_values': {
            'Default': None,
            'Validator':
            lambda value: isinstance(value, dict) and len(value) == 0
        },
        'set_ylim': {
            'Default':
            None,
            'Validator':
            lambda value: isinstance(value, (list, tuple)) and len(value) == 2
            and all([isinstance(v, (int, float)) for v in value])
        },
        'set_ylim_panelB': {
            'Default':
            None,
            'Validator':
            lambda value: isinstance(value, (list, tuple)) and len(value) == 2
            and all([isinstance(v, (int, float)) for v in value])
        },
        'hlines': {
            'Default': None,
            'Validator': lambda value: _hlines_validator(value)
        },
        'vlines': {
            'Default': None,
            'Validator': lambda value: _vlines_validator(value)
        },
        'alines': {
            'Default': None,
            'Validator': lambda value: _alines_validator(value)
        },
        'tlines': {
            'Default': None,
            'Validator': lambda value: _tlines_validator(value)
        },
        'panel_ratios': {
            'Default':
            None,
            'Validator':
            lambda value: isinstance(value, (tuple, list)) and len(value) <= 10
            and all([isinstance(v, (int, float)) for v in value])
        },
        'main_panel': {
            'Default': 0,
            'Validator': lambda value: _valid_panel_id(value)
        },
        'volume_panel': {
            'Default': 1,
            'Validator': lambda value: _valid_panel_id(value)
        },
        'num_panels': {
            'Default':
            None,
            'Validator':
            lambda value: isinstance(value, int) and value in range(1, 10 + 1)
        },
        'datetime_format': {
            'Default': None,
            'Validator': lambda value: isinstance(value, str)
        },
        'xrotation': {
            'Default': 45,
            'Validator': lambda value: isinstance(value, (int, float))
        },
        'axisoff': {
            'Default': False,
            'Validator': lambda value: isinstance(value, bool)
        },
        'closefig': {
            'Default': 'auto',
            'Validator': lambda value: isinstance(value, bool)
        },
        'fill_between': {
            'Default':
            None,
            'Validator':
            lambda value: _num_or_seq_of_num(value) or
            (isinstance(value, dict) and 'y1' in value and _num_or_seq_of_num(
                value['y1']))
        },
        'tight_layout': {
            'Default': False,
            'Validator': lambda value: isinstance(value, bool)
        },
        'width_adjuster_version': {
            'Default': 'v1',
            'Validator': lambda value: value in ('v0', 'v1')
        },
        'scale_width_adjustment': {
            'Default': None,
            'Validator':
            lambda value: isinstance(value, dict) and len(value) > 0
        },
        'update_width_config': {
            'Default': None,
            'Validator':
            lambda value: isinstance(value, dict) and len(value) > 0
        },
        'return_width_config': {
            'Default': None,
            'Validator':
            lambda value: isinstance(value, dict) and len(value) == 0
        },
        'saxbelow': {
            'Default': True,  # Issue#115 Comment#639446764
            'Validator': lambda value: isinstance(value, bool)
        },
    }

    _validate_vkwargs_dict(vkwargs)

    return vkwargs
    def process_color(self,
                      param,
                      colormap_possible=False,
                      bed_rgb_possible=False,
                      colormap_only=False,
                      default_value_is_colormap=False):
        """
        Put a valid color/colormap in self.properties[param]
        Args:
            param: param to check/update the value
            colormap_possible: if the self.properties[param] can be a colormap
            bed_rgb_possible: if the self.properties[param] can be 'bed_rgb'
            colormap_only: if the self.properties[param] must be a colormap

        Returns:
            True if the self.properties[param] is a colormap
            False if the self.properties[param] is not a colormap

        """
        default_value = self.DEFAULTS_PROPERTIES[param]
        valid_color = None
        if bed_rgb_possible and self.properties[param] == 'bed_rgb':
            return False
        if mc.is_color_like(self.properties[param]):
            valid_color = self.properties[param]
        # It can be a tuple (for example (1, 0.88, 2./3) would be a valid color):
        elif self.properties[param][0] == '(':
            try:
                custom_color = eval(self.properties[param])
            except ValueError:
                self.log.warning("*WARNING* {}: '{}' for section {}"
                                 " is not valid. {} has "
                                 "been set to "
                                 "{}".format(param, self.properties[param],
                                             self.properties['section_name'],
                                             default_value))
                valid_color = default_value
            else:
                if mc.is_color_like(custom_color):
                    valid_color = custom_color
                else:
                    self.log.warning("*WARNING* {}: '{}' for section {}"
                                     " is not valid. {} has "
                                     "been set to "
                                     "{}".format(
                                         param, self.properties[param],
                                         self.properties['section_name'],
                                         default_value))
                    valid_color = default_value
        if not colormap_possible:
            if valid_color is None:
                self.log.warning("*WARNING* {}: '{}' for section {}"
                                 " is not valid. It has "
                                 "been set to "
                                 "{}".format(param, self.properties[param],
                                             self.properties['section_name'],
                                             default_value))
                valid_color = default_value
            self.properties[param] = valid_color
            return False
        else:
            valid_colormap = None
            # We will try to process the color as a colormap
            if valid_color is None:
                # If someone what to use its own colormap,
                # he can specify the rgb values or color values:
                # For example:
                # colormap = ['white', (1, 0.88, 2./3), (1, 0.74, 0.25), (1, 0.5, 0), (1, 0.19, 0), (0.74, 0, 0), (0.35, 0, 0)]
                if self.properties[param][0] == '[':
                    try:
                        custom_colors = eval(self.properties[param])
                    except (SyntaxError, NameError) as e:
                        self.log.warning(
                            "Warning: section {}, {} was set as {} but "
                            "raises an error:\n{}\nIt will be ignored and"
                            " default value will be used."
                            "".format(self.properties['section_name'], param,
                                      self.properties[param], e))
                    else:
                        try:
                            valid_colormap = mc.LinearSegmentedColormap.from_list(
                                'custom', custom_colors, N=100)
                        except ValueError as e:
                            self.log.warning(
                                "Warning: section {}, {} was set as {} but "
                                "raises an error:\n{}\nIt will be ignored and"
                                " default value will be used."
                                "".format(self.properties['section_name'],
                                          param, self.properties[param], e))
                else:
                    if self.properties[param] in dir(plt.cm):
                        valid_colormap = self.properties[param]
        # Here, colormap is possible
        # valid_color is None or a valid color or the default value
        # valid_colormap is None or a valid colormap
        if valid_color is None and valid_colormap is None:
            self.log.warning("*WARNING* {}: '{}' for section {}"
                             " is not valid. It has "
                             "been set to "
                             "{}".format(param, self.properties[param],
                                         self.properties['section_name'],
                                         default_value))
            self.properties[param] = default_value
            return default_value_is_colormap
        if colormap_only:
            if valid_colormap is None:
                # valid_color is not None
                self.log.warning("*WARNING* {}: '{}' for section {}"
                                 " is not valid: it is a color whereas"
                                 " a colormap was expected. It has "
                                 "been set to "
                                 "{}".format(param, self.properties[param],
                                             self.properties['section_name'],
                                             default_value))
                valid_colormap = default_value
            self.properties[param] = valid_colormap
            return True
        else:
            if valid_color is not None:
                self.properties[param] = valid_color
                return False
            else:
                self.properties[param] = valid_colormap
                return True
예제 #17
0
 def setup(self):
     for label, value in self.data:
         if label is None and value is None:
             # Separator: (None, None)
             self.formlayout.addRow(QtWidgets.QLabel(" "), QtWidgets.QLabel(" "))
             self.widgets.append(None)
             continue
         elif label is None:
             # Comment
             self.formlayout.addRow(QtWidgets.QLabel(value))
             self.widgets.append(None)
             continue
         elif tuple_to_qfont(value) is not None:
             field = FontLayout(value, self)
         elif (label.lower() not in BLACKLIST
               and mcolors.is_color_like(value)):
             field = ColorLayout(to_qcolor(value), self)
         elif isinstance(value, str):
             field = QtWidgets.QLineEdit(value, self)
         elif isinstance(value, (list, tuple)):
             if isinstance(value, tuple):
                 value = list(value)
             # Note: get() below checks the type of value[0] in self.data so
             # it is essential that value gets modified in-place.
             # This means that the code is actually broken in the case where
             # value is a tuple, but fortunately we always pass a list...
             selindex = value.pop(0)
             field = QtWidgets.QComboBox(self)
             if isinstance(value[0], (list, tuple)):
                 keys = [key for key, _val in value]
                 value = [val for _key, val in value]
             else:
                 keys = value
             field.addItems(value)
             if selindex in value:
                 selindex = value.index(selindex)
             elif selindex in keys:
                 selindex = keys.index(selindex)
             elif not isinstance(selindex, Integral):
                 warnings.warn(
                     "index '%s' is invalid (label: %s, value: %s)" %
                     (selindex, label, value), stacklevel=2)
                 selindex = 0
             field.setCurrentIndex(selindex)
         elif isinstance(value, bool):
             field = QtWidgets.QCheckBox(self)
             if value:
                 field.setCheckState(QtCore.Qt.Checked)
             else:
                 field.setCheckState(QtCore.Qt.Unchecked)
         elif isinstance(value, Integral):
             field = QtWidgets.QSpinBox(self)
             field.setRange(-1e9, 1e9)
             field.setValue(value)
         elif isinstance(value, Real):
             field = QtWidgets.QLineEdit(repr(value), self)
             field.setCursorPosition(0)
             field.setValidator(QtGui.QDoubleValidator(field))
             field.validator().setLocale(QtCore.QLocale("C"))
             dialog = self.get_dialog()
             dialog.register_float_field(field)
             field.textChanged.connect(lambda text: dialog.update_buttons())
         elif isinstance(value, datetime.datetime):
             field = QtWidgets.QDateTimeEdit(self)
             field.setDateTime(value)
         elif isinstance(value, datetime.date):
             field = QtWidgets.QDateEdit(self)
             field.setDate(value)
         else:
             field = QtWidgets.QLineEdit(repr(value), self)
         self.formlayout.addRow(label, field)
         self.widgets.append(field)
예제 #18
0
 def validate_color(value):
     if not is_color_like(value): value='None'
     return value         
예제 #19
0
    def plot_profile(self):

        if not self.color_list:
            cmap_plot = plt.get_cmap('jet')
            if self.numlines > 1:
                # kmeans, so we need to color by cluster
                self.color_list = cmap_plot(np.arange(self.numlines, dtype=float) / self.numlines)
            else:
                self.color_list = cmap_plot(np.arange(self.numplots, dtype=float) / self.numplots)
        if (self.numlines > 1 and len(self.color_list) < self.numlines) or\
           (self.numlines == 1 and len(self.color_list) < self.numplots):
            sys.exit("\nThe given list of colors is too small, "
                     "at least {} colors are needed\n".format(self.numlines))
        for color in self.color_list:
            if not pltcolors.is_color_like(color):
                sys.exit("\nThe color name {} is not valid. Check "
                         "the name or try with a html hex string "
                         "for example #eeff22".format(color))

        first = True
        ax_list = []
        for plot in range(self.numplots):
            col = plot % self.plots_per_row
            row = int(plot / self.plots_per_row)
            if row == 0 and col == 0:
                ax = self.fig.add_subplot(self.grids[row, col])
            else:
                ax = self.fig.add_subplot(self.grids[row, col], sharey=ax_list[0])

            if self.per_group:
                title = self.hm.matrix.group_labels[plot]
                if row != 0:
                    plt.setp(ax.get_yticklabels(), visible=False)
            else:
                title = self.hm.matrix.sample_labels[plot]
                if col != 0:
                    plt.setp(ax.get_yticklabels(), visible=False)

            ax.set_title(title)
            for data_idx in range(self.numlines):
                if self.per_group:
                    _row, _col = plot, data_idx
                else:
                    _row, _col = data_idx, plot

                sub_matrix = self.hm.matrix.get_matrix(_row, _col)

                if self.per_group:
                    label = sub_matrix['sample']
                else:
                    label = sub_matrix['group']

                if self.numlines > 1:
                    coloridx = data_idx
                else:
                    coloridx = plot
                plot_single(ax, sub_matrix['matrix'],
                            self.averagetype,
                            self.color_list[coloridx],
                            label,
                            plot_type=self.plot_type)

            # remove the numbers of the y axis for all plots
            plt.setp(ax.get_yticklabels(), visible=False)

            if col == 0:
                # add the y axis label for the first plot
                # on each row and make the numbers and ticks visible
                plt.setp(ax.get_yticklabels(), visible=True)
                ax.axes.set_ylabel(self.y_axis_label)
                """
                # reduce the number of yticks by half
                num_ticks = len(ax.get_yticks())
                yticks = [ax.get_yticks()[i] for i in range(1, num_ticks, 2)]
                ax.set_yticks(yticks)
                """

            ax.axes.set_xticks(self.xticks)
            ax.axes.set_xticklabels(self.xtickslabel)
            # align the first and last label
            # such that they don't fall off
            # the heatmap sides
            ticks = ax.xaxis.get_major_ticks()
            ticks[0].label1.set_horizontalalignment('left')
            ticks[-1].label1.set_horizontalalignment('right')

            if first and self.plot_type not in ['heatmap', 'overlapped_lines']:
                ax.legend(loc=self.legend_location.replace('-', ' '),
                          ncol=1, prop=self.font_p,
                          frameon=False, markerscale=0.5)
                first = False

            """
            ax.legend(bbox_to_anchor=(-0.05, -1.13, 1., 1),
                      loc='upper center',
                      ncol=1, mode="expand", prop=font_p,
                      frameon=False, markerscale=0.5)
            """

            lims = ax.get_ylim()
            if self.y_min is not None:
                lims = (self.y_min, lims[1])
            if self.y_max is not None:
                lims = (lims[0], self.y_max)
            if lims[0] >= lims[1]:
                lims = (lims[0], lims[0] + 1)
            ax.set_ylim(lims)

            ax_list.append(ax)

        plt.subplots_adjust(wspace=0.05, hspace=0.3)
        plt.tight_layout()
        plt.savefig(self.out_file_name, dpi=200, format=self.image_format)
        plt.close()
예제 #20
0
    def AverageDistributionsCI(self,means,stds,nstd,datatype,labels,colors,title,xlabel,ylabel,is_legend,legend_location):
        """      
        Plots the average and standard deviation.

        Input:
         - *means* (nested list)
         - *stds* (nested list)
         - *nstd* (float)
         - *labels* (list)
         - *linestyle* (string)
         - *linewidth* (float)
         - *marker* (string)
         - *colors* (list)
         - *title* (string)
         - *xlabel* (string)
         - *ylabel* (string)
         - *is_legend* (boolean)
         - *legend_location* [default = 'upper right'] (string/integer)
        """  
        assert nstd > 0, "Error: The number of STDs must be a value larger than zero"      
        plt.figure(self.plotnum)
        datatype_indices = [labels.index(Id) for Id in datatype]           
        for i in datatype_indices:   
            L_s_amount = copy.copy(means[i][0])
            L_mu =  copy.copy(means[i][1])
            L_sigma =  copy.copy(stds[i][1])

            # Add an additional value
            L_s_amount.append(L_s_amount[-1]+1)
            L_mu.append(L_mu[-1])
            L_sigma.append(L_sigma[-1])

            X_i = []
            Y_i = []
            L_errors = []
            for j in range(len(L_s_amount)):
                if (not L_s_amount[j] == L_s_amount[0]) and (not L_s_amount[j] == L_s_amount[-1]):
                    X_i.append(L_s_amount[j])
                    Y_i.append(L_mu[j-1])
                    L_errors.append(L_sigma[j-1])
                X_i.append(L_s_amount[j])
                Y_i.append(L_mu[j])
                L_errors.append(L_sigma[j])
            X_e = np.concatenate([X_i, X_i[::-1]])
            Y_e = np.concatenate([np.array(Y_i) - nstd*np.array(L_errors) ,(np.array(Y_i) + nstd*np.array(L_errors))[::-1]])   
        
            if colors == None:              
                if j >= len(self.colors):                  
                    j=0
            elif isinstance(colors,list):
                if j >= len(colors):
                    j=0
            elif isinstance(colors,str):
                colors = [colors]
                j=0
            if colors == None:                         
                plt.fill(X_e-0.5,Y_e,  alpha=.25, ec='None', label='{0} STD confidence interval'.format(nstd),color = self.colors[j]) 
                plt.plot(np.array(X_i)-0.5,np.array(Y_i),color = self.colors[j])
            else:
                if clr.is_color_like(colors[j]):     
                    plt.fill(X_e-0.5,Y_e,  alpha=.25, ec='None', label='{0} STD confidence interval'.format(nstd),color = colors[j]) 
                    plt.plot(np.array(X_i)-0.5,np.array(Y_i),color = colors[j])
                else:
                    print("*** WARNING ***: '{0}' is not recognized as a valid color code".format(colors[j]) )
                    plt.fill(X_e-0.5,Y_e,  alpha=.25, ec='None', label='{0} STD confidence interval'.format(nstd),color = self.colors[j]) 
                    plt.plot(np.array(X_i)-0.5,np.array(Y_i),color = self.colors[j])      
                    colors = None
        if is_legend:
            plt.legend(numpoints=1,frameon=True,loc=legend_location)
        plt.xlabel(xlabel)
        plt.ylabel(ylabel)
        plt.title(title)        
예제 #21
0
 def setup(self):
     for label, value in self.data:
         if label is None and value is None:
             # Separator: (None, None)
             self.formlayout.addRow(QtWidgets.QLabel(" "),
                                    QtWidgets.QLabel(" "))
             self.widgets.append(None)
             continue
         elif label is None:
             # Comment
             self.formlayout.addRow(QtWidgets.QLabel(value))
             self.widgets.append(None)
             continue
         elif tuple_to_qfont(value) is not None:
             field = FontLayout(value, self)
         elif (label.lower() not in BLACKLIST
               and mcolors.is_color_like(value)):
             field = ColorLayout(to_qcolor(value), self)
         elif isinstance(value, str):
             field = QtWidgets.QLineEdit(value, self)
         elif isinstance(value, (list, tuple)):
             if isinstance(value, tuple):
                 value = list(value)
             # Note: get() below checks the type of value[0] in self.data so
             # it is essential that value gets modified in-place.
             # This means that the code is actually broken in the case where
             # value is a tuple, but fortunately we always pass a list...
             selindex = value.pop(0)
             field = QtWidgets.QComboBox(self)
             if isinstance(value[0], (list, tuple)):
                 keys = [key for key, _val in value]
                 value = [val for _key, val in value]
             else:
                 keys = value
             field.addItems(value)
             if selindex in value:
                 selindex = value.index(selindex)
             elif selindex in keys:
                 selindex = keys.index(selindex)
             elif not isinstance(selindex, Integral):
                 _log.warning(
                     "index '%s' is invalid (label: %s, value: %s)",
                     selindex, label, value)
                 selindex = 0
             field.setCurrentIndex(selindex)
         elif isinstance(value, bool):
             field = QtWidgets.QCheckBox(self)
             if value:
                 field.setCheckState(QtCore.Qt.Checked)
             else:
                 field.setCheckState(QtCore.Qt.Unchecked)
         elif isinstance(value, Integral):
             field = QtWidgets.QSpinBox(self)
             field.setRange(-10**9, 10**9)
             field.setValue(value)
         elif isinstance(value, Real):
             field = QtWidgets.QLineEdit(repr(value), self)
             field.setCursorPosition(0)
             field.setValidator(QtGui.QDoubleValidator(field))
             field.validator().setLocale(QtCore.QLocale("C"))
             dialog = self.get_dialog()
             dialog.register_float_field(field)
             field.textChanged.connect(lambda text: dialog.update_buttons())
         elif isinstance(value, datetime.datetime):
             field = QtWidgets.QDateTimeEdit(self)
             field.setDateTime(value)
         elif isinstance(value, datetime.date):
             field = QtWidgets.QDateEdit(self)
             field.setDate(value)
         else:
             field = QtWidgets.QLineEdit(repr(value), self)
         self.formlayout.addRow(label, field)
         self.widgets.append(field)
예제 #22
0
def show(ar,
         figsize=(8, 8),
         cmap='gray',
         scaling='none',
         clipvals='minmax',
         min=None,
         max=None,
         power=1,
         bordercolor=None,
         borderwidth=5,
         returnclipvals=False,
         returncax=False,
         returnfig=False,
         figax=None,
         hist=False,
         n_bins=256,
         mask=None,
         mask_color='k',
         mask_alpha=0.,
         rectangle=None,
         circle=None,
         annulus=None,
         ellipse=None,
         points=None,
         grid_overlay=None,
         cartesian_grid=None,
         polarelliptical_grid=None,
         rtheta_grid=None,
         scalebar=None,
         coordinates=None,
         rx=None,
         ry=None,
         space='Q',
         pixelsize=None,
         pixelunits=None,
         x0=None,
         y0=None,
         e=None,
         theta=None,
         **kwargs):
    """
    General visualization function for 2D arrays.

    The simplest use of this function is::

        >>> show(ar)

    which will generate and display a matplotlib figure showing the 2D array ``ar``.
    Additional functionality includes:

        * scaling the image (log scaling, power law scaling)
        * displaying the image histogram
        * altering the histogram clip values
        * masking some subset of the image
        * setting the colormap
        * adding geometric overlays (e.g. points, circles, rectangles, annuli)
        * adding informational overlays (scalebars, coordinate grids, oriented axes or
          vectors)
        * further customization tools

    These are each discussed in turn below.

    Scaling:
        Setting the parameter ``scaling`` will scale the display image. Options are
        'none', 'power', or 'log'.  If 'power' is specified, the parameter ``power`` must
        also be passed. The underlying data is not altered. Values less than or equal to
        zero are set to zero. If the image histogram is displayed using ``hist=True``,
        the scaled image histogram is shown.

        Examples::

            >>> show(ar,scaling='log')
            >>> show(ar,scaling='power',power=0.5)
            >>> show(ar,scaling='power',power=0.5,hist=True)

    Histogram:
        Setting the argument ``hist=True`` will display the image histogram, instead of
        the image. The displayed histogram will reflect any scaling requested. The number
        of bins can be set with ``n_bins``. The upper and lower clip values, indicating
        where the image display will be saturated, are shown with dashed lines.

    Clip values:
        By 'clip values' we mean the lower and upper values at which the display image
        will be saturated. Controlling the clip values is accomplished using the input
        parameters ``clipvals``, ``min``, and ``max``, and the clipvalues can be returned
        with the ``returnclipvals`` parameter.  ``clipvals`` controls the method by which
        the clip values are determined, and must be a string in ('minmax','manual',
        'std','centered'). Their behaviors are
            * 'minmax' (default): The min/max values are set to np.min(ar)/np.max(ar)
            * 'manual': The min/max values are set to ``min``/``max``
            * 'std': The min/max values are ``np.median(ar) + N*np.std(ar)``, and
               N is this functions ``min``/``max`` values.
            * 'centered': The min/max values are set to ``c -/+ m``, where by default
              'c' is zero and m is the max(abs(ar-c)), or, the two params can be user
              specified using  ``min``/``max`` -> ``c``/``m``.

    Masking:
        If a numpy masked array is passed to show, the function will automatically
        mask the appropriate pixels. Alternatively, a boolean array of the same shape as
        the data array may be passed to the ``mask`` argument, and these pixels will be
        masked.  Masked pixels are displayed as a single uniform color, black by default,
        and which can be specified with the ``mask_color`` argument.  Masked pixels
        are excluded when displaying the histogram or computing clip values. The mask
        can also be blended with the hidden data by setting the ``mask_alpha`` argument.

    Overlays (geometric):
        The function natively supports overlaying points, circles, rectangles, annuli,
        and ellipses. Each is invoked by passing a dictionary to the appropriate input
        variable specifying the geometry and features of the requested overlay. For
        example:

            >>> show(ar, rectangle={'lims':(10,20,10,20),'color':'r'})

        will overlay a single red square, and

            >>> show(ar, annulus={'center':[(28,68),(92,160)],'fill':True,
                                  'alpha':[0.9,0.3],'Ri':[16,12],'Ro':[24,36],
                                  'color':['r',(0,1,1,1)]})

        will overlay two annuli with two different centers, radii, colors, and
        transparencies. For a description of the accepted dictionary parameters
        for each type of overlay, see the visualize functions add_*, where
        * = ('rectangle','circle','annulus','ellipse','points'). (These docstrings
        are under construction!)

    Overlays (informational):
        Informational overlays supported by this function include coordinate axes
        (cartesian, polar-elliptical, or r-theta) and scalebars.  These are added
        by passing the appropriate input argument a dictionary of the desired
        parameters, as with geometric overlays. However, there are two key differences
        between these overlays and the geometric overlays.  First, informational
        overlays (coordinate systems and scalebars) require information about the
        plot - e.g. the position of the origin, the pixel sizes, the pixel units,
        any elliptical distortions, etc.  The easiest way to pass this information
        is by pass a Coordinates object containing this info to ``show`` as the
        keyword ``coordinates``. Second, once the coordinate information has been
        passed, informational overlays can autoselect their own parameters, thus simply
        passing an empty dict to one of these parameters will add that overlay.

        For example:

            >>> show(dp, scalebar={}, coordinates=coords)

        will display the diffraction pattern ``dp`` with a scalebar overlaid in the
        bottom left corner given the pixel size and units described in ``coords``,
        and

            >>> show(dp, coordinates=coords, scalebar={'length':0.5,'width':2,
                                                       'position':'ul','label':True'})

        will display a more customized scalebar.

        When overlaying coordinate grids, it is important to note that some relevant
        parameters, e.g. the position of the origin, may change by scan position.
        In these cases, the parameters ``rx``,``ry`` must also be passed to ``show``,
        to tell the ``Coordinates`` object where to look for the relevant parameters.
        For example:

            >>> show(dp, cartesian_grid={}, coordinates=coords, rx=2,ry=5)

        will overlay a cartesian coordinate grid on the diffraction pattern at scan
        position (2,5). Adding

            >>> show(dp, coordinates=coords, rx=2, ry=5, cartesian_grid={'label':True,
                        'alpha':0.7,'color':'r'})

        will customize the appearance of the grid further. And

            >>> show(im, coordinates=coords, cartesian_grid={}, space='R')

        displays a cartesian grid over a real space image.  For more details, see the
        documentation for the visualize functions add_*, where * = ('scalebar',
        'cartesian_grid', 'polarelliptical_grid', 'rtheta_grid'). (Under construction!)

    Further customization:
        Most parameters accepted by a matplotlib axis will be accepted by ``show``.
        Pass a valid matplotlib colormap or a known string indicating a colormap
        as the argument ``cmap`` to specify the colormap.  Pass ``figsize`` to
        specify the figure size.  Etc.

        Further customization can be accomplished by either (1) returning the figure
        generated by show and then manipulating it using the normal matplotlib
        functions, or (2) generating a matplotlib Figure with Axes any way you like
        (e.g. with ``plt.subplots``) and then using this function to plot inside a
        single one of the Axes of your choice.

        Option (1) is accomplished by simply passing this function ``returnfig=True``.
        Thus:

            >>> fig,ax = show(ar, returnfig=True)

        will now give you direct access to the figure and axes to continue to alter.
        Option (2) is accomplished by passing an existing figure and axis to ``show``
        as a 2-tuple to the ``figax`` argument. Thus:

            >>> fig,(ax1,ax2) = plt.subplots(1,2)
            >>> show(ar, figax=(fig,ax1))
            >>> show(ar, figax=(fig,ax2), hist=True)

        will generate a 2-axis figure, and then plot the array ``ar`` as an image on
        the left, while plotting its histogram on the right.


    Args:
        ar (2D array): the array to plot
        figsize (2-tuple): size of the plot
        cmap (colormap): any matplotlib cmap; default is gray
        scaling (str): selects a scaling scheme for the intensity values. Default is
            none. Accepted values:
                * 'none'
                * 'log': values where ar<=0 are set to 0
                * 'power': requires the 'power' argument be set.
                  values where ar<=0 are set to 0
        clipvals (str): method for setting clipvalues.  Default is the array min and max
            values. Accepted values:
                * 'minmax': The min/max values are np.min(ar)/np.max(r)
                * 'manual': The min/max values are set to the values of
                  the min,max arguments received by this function
                * 'std': The min/max values are ``np.median(ar) -/+ N*np.std(ar)``, and
                   N is this functions min,max vals.
                * 'centered': The min/max values are set to ``c -/+ m``, where by default
                  'c' is zero and m is the max(abs(ar-c), or the two params can be user
                  specified using the kwargs min/max -> c/m.
        min (number): behavior depends on clipvals
        max (number): behavior depends on clipvals
        power (number): when ``scaling='power'``, specifies the scaling power
        bordercolor (color or None): if not None, add a border of this color.
            The color can be anything matplotlib recognizes as a color.
        borderwidth (number):
        returnfig (bool): if True, the function returns the tuple (figure,axis)
        figax (None or 2-tuple): controls which matplotlib Axes object draws the image.
            If None, generates a new figure with a single Axes instance. Otherwise, ax
            must be a 2-tuple containing the matplotlib class instances (Figure,Axes),
            with ar then plotted in the specified Axes instance.
        hist (bool): if True, instead of plotting a 2D image in ax, plots a histogram of
            the intensity values of ar, after any scaling this function has performed.
            Plots the clipvals as dashed vertical lines
        n_bins (int): number of hist bins
        mask (None or boolean array): if not None, must have the same shape as 'ar'.
            Wherever mask==True, plot the pixel normally, and where ``mask==False``,
            pixel values are set to mask_color. If hist==True, ignore these values in the
            histogram. If ``mask_alpha`` is specified, the mask is blended with the array
            underneath, with 0 yielding an opaque mask and 1 yielding a fully transparent
            mask. If ``mask_color`` is set to ``'empty'`` instead of a matplotlib.color,
            nothing is done to pixels where ``mask==False``, allowing overlaying multiple
            arrays in different regions of an image by invoking the ``figax` kwarg over
            multiple calls to show
        mask_color (color): see 'mask'
        mask_alpha (float): see 'mask'
        **kwargs: any keywords accepted by matplotlib's ax.matshow()

    Returns:
        if returnfig==False (default), the figure is plotted and nothing is returned.
        if returnfig==True, return the figure and the axis.
    """
    assert scaling in ('none', 'log', 'power', 'hist')
    assert clipvals in ('minmax', 'manual', 'std', 'centered')
    if mask is not None:
        assert mask.shape == ar.shape
        assert is_color_like(mask_color) or mask_color == 'empty'
        if isinstance(ar, np.ma.masked_array):
            ar = np.ma.array(data=ar.data, mask=np.logical_or(ar.mask, ~mask))
        else:
            ar = np.ma.array(data=ar, mask=~mask)
    elif isinstance(ar, np.ma.masked_array):
        pass
    else:
        mask = np.ones_like(ar, dtype=bool)
        ar = np.ma.array(data=ar, mask=mask == False)

    # Perform any scaling
    if scaling == 'none':
        _ar = ar.copy()
        _mask = np.ones_like(_ar.data, dtype=bool)
    elif scaling == 'log':
        _mask = ar.data > 0
        _ar = np.zeros_like(ar.data, dtype=float)
        _ar[_mask] = np.log(ar.data[_mask])
        _ar[~_mask] = np.nan
        if clipvals == 'manual':
            if min != None:
                if min > 0: min = np.log(min)
                else: min = np.min(_ar[_mask])
            if max != None: max = np.log(max)
    elif scaling == 'power':
        _mask = ar.data > 0
        _ar = np.zeros_like(ar.data, dtype=float)
        _ar[_mask] = np.power(ar.data[_mask], power)
        _ar[~_mask] = np.nan
        if clipvals == 'manual':
            if min != None: min = np.power(min, power)
            if max != None: max = np.power(max, power)
    else:
        raise Exception

    _ar = np.ma.array(data=_ar.data, mask=~_mask)

    # Set the clipvalues
    if clipvals == 'minmax':
        vmin, vmax = np.nanmin(_ar), np.nanmax(_ar)
    elif clipvals == 'manual':
        assert min is not None and max is not None
        vmin, vmax = min, max
    elif clipvals == 'std':
        assert min is not None and max is not None
        m, s = np.nanmedian(_ar), np.nanstd(_ar)
        vmin = m + min * s
        vmax = m + max * s
    elif clipvals == 'centered':
        c = np.nanmean(_ar) if min is None else min
        m = np.nanmax(np.ma.abs(c - _ar)) if max is None else max
        vmin = c - m
        vmax = c + m
    else:
        raise Exception

    # Create or attach to the appropriate Figure and Axis
    if figax is None:
        fig, ax = plt.subplots(1, 1, figsize=figsize)
    else:
        fig, ax = figax
        assert (isinstance(fig, Figure))
        assert (isinstance(ax, Axes))

    # Create the masked array applying the user mask (this is done after the
    # vmin and vmax are determined so the mask doesn't affect those)
    _ar = np.ma.array(data=_ar.data, mask=np.logical_or(ar.mask, ~_mask))

    # Create colormap with mask_color for bad values
    cm = copy(plt.cm.get_cmap(cmap))
    if mask_color == 'empty':
        cm.set_bad(alpha=0)
    else:
        cm.set_bad(color=mask_color)

    # Plot the image
    if not hist:
        cax = ax.matshow(_ar, vmin=vmin, vmax=vmax, cmap=cm, **kwargs)
        if np.any(_ar.mask):
            mask_display = np.ma.array(data=_ar.data, mask=~_ar.mask)
            ax.matshow(mask_display,
                       cmap=cmap,
                       alpha=mask_alpha,
                       vmin=vmin,
                       vmax=vmax)
    # ...or, plot its histogram
    else:
        hist, bin_edges = np.histogram(_ar,
                                       bins=np.linspace(np.min(_ar),
                                                        np.max(_ar),
                                                        num=n_bins))
        w = bin_edges[1] - bin_edges[0]
        x = bin_edges[:-1] + w / 2.
        ax.bar(x, hist, width=w)
        ax.vlines((vmin, vmax), 0, ax.get_ylim()[1], color='k', ls='--')

    # Add a border
    if bordercolor is not None:
        for s in ['bottom', 'top', 'left', 'right']:
            ax.spines[s].set_color(bordercolor)
            ax.spines[s].set_linewidth(borderwidth)
        ax.set_xticks([])
        ax.set_yticks([])

    # Add shape/point overlays
    if rectangle is not None:
        add_rectangles(ax, rectangle)
    if circle is not None:
        add_circles(ax, circle)
    if annulus is not None:
        add_annuli(ax, annulus)
    if ellipse is not None:
        add_ellipses(ax, ellipse)
    if points is not None:
        add_points(ax, points)
    if grid_overlay is not None:
        add_grid_overlay(ax, grid_overlay)

    # Parse arguments for scale/coordinate overlays
    if coordinates is not None:
        assert isinstance(coordinates, Coordinates)
    assert space in ('Q', 'R')
    # pixel size/units
    if pixelsize is None and coordinates is None:
        pixelsize = 1
    if pixelsize is not None:
        pass
    else:
        if space == 'Q':
            pixelsize = coordinates.get_Q_pixel_size()
        else:
            pixelsize = coordinates.get_R_pixel_size()
    if pixelunits is None and coordinates is None:
        pixelunits = 'pixels'
    if pixelunits is not None:
        pass
    else:
        if space == 'Q':
            pixelunits = coordinates.get_Q_pixel_units()
        else:
            pixelunits = coordinates.get_R_pixel_units()
    # origin
    if space == 'Q':
        if x0 is not None:
            pass
        elif coordinates is not None:
            try:
                x0 = coordinates.get_qx0(rx, ry)
            except AttributeError:
                raise Exception(
                    'The Coordinates instance passed does not contain a value for qx0'
                )
        else:
            x0 = 0
        if y0 is not None:
            pass
        elif coordinates is not None:
            try:
                y0 = coordinates.get_qy0(rx, ry)
            except AttributeError:
                raise Exception(
                    'The Coordinates instance passed does not contain a value for qy0'
                )
        else:
            y0 = 0
    else:
        x0 = x0 if x0 is not None else 0
        y0 = y0 if y0 is not None else 0
    # ellipticity
    if space == 'Q':
        if e is not None:
            pass
        elif coordinates is not None:
            try:
                e = coordinates.get_e(rx, ry)
            except AttributeError:
                raise Exception(
                    'The Coordinates instance passed does not contain a value for e'
                )
        else:
            e = 1
        if theta is not None:
            pass
        elif coordinates is not None:
            try:
                theta = coordinates.get_theta(rx, ry)
            except AttributeError:
                raise Exception(
                    'The Coordinates instance passed does not contain a value for theta'
                )
        else:
            theta = 0
    else:
        e = e if e is not None else 1
        theta = theta if theta is not None else 0

    # Add a scalebar
    if scalebar is not None:
        # Add the grid
        scalebar['Nx'], scalebar['Ny'] = ar.shape
        scalebar['pixelsize'] = pixelsize
        scalebar['pixelunits'] = pixelunits
        scalebar['space'] = space
        add_scalebar(ax, scalebar)

    # Add cartesian grid
    if cartesian_grid is not None:
        Nx, Ny = ar.shape
        assert isinstance(
            x0, Number
        ), "Error: x0 must be a number. If a Coordinate system was passed, try passing a position (rx,ry)."
        assert isinstance(
            y0, Number
        ), "Error: y0 must be a number. If a Coordinate system was passed, try passing a position (rx,ry)."
        cartesian_grid['x0'], cartesian_grid['y0'] = x0, y0
        cartesian_grid['Nx'], cartesian_grid['Ny'] = Nx, Ny
        cartesian_grid['pixelsize'] = pixelsize
        cartesian_grid['pixelunits'] = pixelunits
        cartesian_grid['space'] = space
        add_cartesian_grid(ax, cartesian_grid)

    # Add polarelliptical grid
    if polarelliptical_grid is not None:
        Nx, Ny = ar.shape
        assert isinstance(
            x0, Number
        ), "Error: x0 must be a number. If a Coordinate system was passed, try passing a position (rx,ry)."
        assert isinstance(
            y0, Number
        ), "Error: y0 must be a number. If a Coordinate system was passed, try passing a position (rx,ry)."
        assert isinstance(
            e, Number
        ), "Error: e must be a number. If a Coordinate system was passed, try passing a position (rx,ry)."
        assert isinstance(
            theta, Number
        ), "Error: theta must be a number. If a Coordinate system was passed, try passing a position (rx,ry)."
        polarelliptical_grid['x0'], polarelliptical_grid['y0'] = x0, y0
        polarelliptical_grid['e'], polarelliptical_grid['theta'] = e, theta
        polarelliptical_grid['Nx'], polarelliptical_grid['Ny'] = Nx, Ny
        polarelliptical_grid['pixelsize'] = pixelsize
        polarelliptical_grid['pixelunits'] = pixelunits
        polarelliptical_grid['space'] = space
        add_polarelliptical_grid(ax, polarelliptical_grid)

    # Add r-theta grid
    if rtheta_grid is not None:
        add_rtheta_grid(ax, rtheta_grid)

    # Show or return
    returnval = []
    if returnfig: returnval.append((fig, ax))
    if returnclipvals:
        if scaling == 'log':
            vmin, vmax = np.power(np.e, vmin), np.power(np.e, vmax)
        elif scaling == 'power':
            vmin, vmax = np.power(vmin, 1 / power), np.power(vmax, 1 / power)
        returnval.append((vmin, vmax))
    if returncax: returnval.append(cax)
    if len(returnval) == 0:
        if figax is None:
            plt.show()
        return
    elif (len(returnval)) == 1:
        return returnval[0]
    else:
        return tuple(returnval)
예제 #23
0
"""
======================
Link to other packages
======================

Use :mod:`sphinx_gallery` to link to other packages, like
:mod:`numpy`, :mod:`matplotlib.colors`, and :mod:`matplotlib.pyplot`.

FYI this gallery uses :obj:`sphinx_gallery.sorting.FileNameSortKey`.
"""

import numpy as np
from matplotlib.colors import is_color_like
import matplotlib
import matplotlib.pyplot as plt

from local_module import N  # N = 1000

t = np.arange(N) / float(N)
win = np.hanning(N)
print(is_color_like('r'))
plt.figure()
plt.plot(t, win, color='r')
plt.text(0, 1, 'png', size=40, va='top')
orig_dpi = 80. if matplotlib.__version__[0] < '2' else 100.
assert plt.rcParams['figure.dpi'] == orig_dpi
plt.rcParams['figure.dpi'] = 70.
assert plt.rcParams['figure.dpi'] == 70.
예제 #24
0
def plot_linestring_collection(ax,
                               geoms,
                               values=None,
                               color=None,
                               cmap=None,
                               vmin=None,
                               vmax=None,
                               **kwargs):
    """
    Plots a collection of LineString and MultiLineString geometries to `ax`

    Parameters
    ----------

    ax : matplotlib.axes.Axes
        where shapes will be plotted

    geoms : a sequence of `N` LineStrings and/or MultiLineStrings (can be
            mixed)

    values : a sequence of `N` values, optional
        Values will be mapped to colors using vmin/vmax/cmap. They should
        have 1:1 correspondence with the geometries (not their components).

    color : single color or sequence of `N` colors
        Cannot be used together with `values`.

    Returns
    -------

    collection : matplotlib.collections.Collection that was plotted

    """
    from matplotlib.collections import LineCollection
    from matplotlib.colors import is_color_like

    geoms, multiindex = _flatten_multi_geoms(geoms)
    if values is not None:
        values = np.take(values, multiindex, axis=0)

    # LineCollection does not accept some kwargs.
    if "markersize" in kwargs:
        del kwargs["markersize"]

    # color=None gives black instead of default color cycle
    if color is not None:
        if is_color_like(color):
            kwargs["color"] = color
        elif pd.api.types.is_list_like(color):
            kwargs["color"] = np.take(color, multiindex, axis=0)
        else:
            raise TypeError(
                "Color attribute has to be a single color or sequence of colors."
            )

    segments = [np.array(linestring)[:, :2] for linestring in geoms]
    collection = LineCollection(segments, **kwargs)

    if values is not None:
        collection.set_array(np.asarray(values))
        collection.set_cmap(cmap)
        if "norm" not in kwargs:
            collection.set_clim(vmin, vmax)

    ax.add_collection(collection, autolim=True)
    ax.autoscale_view()
    return collection
예제 #25
0
def velocity_embedding(adata,
                       basis=None,
                       vkey='velocity',
                       density=None,
                       arrow_size=None,
                       arrow_length=None,
                       scale=None,
                       X=None,
                       V=None,
                       recompute=None,
                       color=None,
                       use_raw=None,
                       layer=None,
                       color_map=None,
                       colorbar=True,
                       palette=None,
                       size=None,
                       alpha=.2,
                       perc=None,
                       sort_order=True,
                       groups=None,
                       components=None,
                       projection='2d',
                       legend_loc='none',
                       legend_fontsize=None,
                       legend_fontweight=None,
                       xlabel=None,
                       ylabel=None,
                       title=None,
                       fontsize=None,
                       figsize=None,
                       dpi=None,
                       frameon=None,
                       show=True,
                       save=None,
                       ax=None,
                       ncols=None,
                       **kwargs):
    """\
    Scatter plot of velocities on the embedding.

    Arguments
    ---------
    adata: :class:`~anndata.AnnData`
        Annotated data matrix.
    vkey: `str` or `None` (default: `None`)
        Key for annotations of observations/cells or variables/genes.
    density: `float` (default: 1)
        Amount of velocities to show - 0 none to 1 all
    arrow_size: `float` or 3-tuple for headlength, headwidth and headaxislength (default: 1)
        Size of arrows.
    arrow_length: `float` (default: 1)
        Length of arrows.
    scale: `float` (default: 1)
        Length of velocities in the embedding.
    {scatter}

    Returns
    -------
        `matplotlib.Axis` if `show==False`
    """
    #fkeys = ['adata', 'show', 'save', 'groups', 'figsize', 'dpi', 'ncols', 'wspace', 'hspace', 'ax', 'kwargs']

    vkey = [
        key for key in adata.layers.keys()
        if 'velocity' in key and '_u' not in key
    ] if vkey == 'all' else vkey
    layers, vkeys, colors = make_unique_list(layer), make_unique_list(
        vkey), make_unique_list(color, allow_array=True)
    bases = [
        default_basis(adata) if basis is None else basis
        for basis in make_unique_valid_list(adata, basis)
    ]

    if V is None:
        for key in vkeys:
            for basis in bases:
                if recompute or velocity_embedding_changed(
                        adata, basis=basis, vkey=key):
                    compute_velocity_embedding(adata, basis=basis, vkey=key)

    scatter_kwargs = {
        "perc": perc,
        "use_raw": use_raw,
        "sort_order": sort_order,
        "alpha": alpha,
        "components": components,
        "projection": projection,
        "legend_loc": legend_loc,
        "groups": groups,
        "legend_fontsize": legend_fontsize,
        "legend_fontweight": legend_fontweight,
        "palette": palette,
        "color_map": color_map,
        "frameon": frameon,
        "xlabel": xlabel,
        "ylabel": ylabel,
        "colorbar": colorbar,
        "dpi": dpi,
        "fontsize": fontsize,
        "show": False,
        "save": False
    }

    multikey = colors if len(colors) > 1 else layers if len(layers) > 1 \
        else vkeys if len(vkeys) > 1 else bases if len(bases) > 1 else None
    if multikey is not None:
        if title is None: title = list(multikey)
        elif isinstance(title, (list, tuple)):
            title *= int(np.ceil(len(multikey) / len(title)))
        ncols = len(multikey) if ncols is None else min(len(multikey), ncols)
        nrows = int(np.ceil(len(multikey) / ncols))
        figsize = rcParams['figure.figsize'] if figsize is None else figsize
        ax = []
        for i, gs in enumerate(
                pl.GridSpec(
                    nrows, ncols,
                    pl.figure(None, (figsize[0] * ncols, figsize[1] * nrows),
                              dpi=dpi))):
            if i < len(multikey):
                ax.append(
                    velocity_embedding(
                        adata,
                        density=density,
                        scale=scale,
                        size=size,
                        ax=pl.subplot(gs),
                        arrow_size=arrow_size,
                        arrow_length=arrow_length,
                        basis=bases[i] if len(bases) > 1 else basis,
                        color=colors[i] if len(colors) > 1 else color,
                        layer=layers[i] if len(layers) > 1 else layer,
                        vkey=vkeys[i] if len(vkeys) > 1 else vkey,
                        title=title[i] if isinstance(title,
                                                     (list, tuple)) else title,
                        **scatter_kwargs,
                        **kwargs))
        savefig_or_show(dpi=dpi, save=save, show=show)
        if not show: return ax

    else:
        if projection == '3d':
            from mpl_toolkits.mplot3d import Axes3D
            ax = pl.figure(None, figsize, dpi=dpi).gca(
                projection=projection) if ax is None else ax
        else:
            ax = pl.figure(None, figsize, dpi=dpi).gca() if ax is None else ax

        color, layer, vkey, basis = colors[0], layers[0], vkeys[0], bases[0]
        color = default_color(adata) if color is None else color
        color_map = default_color_map(
            adata, color) if color_map is None else color_map
        size = default_size(adata) / 2 if size is None else size
        if use_raw is None and 'Ms' not in adata.layers.keys(): use_raw = True
        _adata = adata[groups_to_bool(
            adata, groups, groupby=color
        )] if groups is not None and color in adata.obs.keys() else adata

        quiver_kwargs = {
            "scale": scale,
            "cmap": color_map,
            "angles": 'xy',
            "scale_units": 'xy',
            "edgecolors": 'k',
            "linewidth": .1,
            "width": None
        }
        if basis in adata.var_names:
            x = adata[:, basis].layers[
                'spliced'] if use_raw else adata[:, basis].layers['Ms']
            y = adata[:, basis].layers[
                'unspliced'] if use_raw else adata[:, basis].layers['Mu']
            dx = adata[:, basis].layers[vkey]
            dy = adata[:,
                       basis].layers[vkey +
                                     '_u'] if vkey + '_u' in adata.layers.keys(
                                     ) else np.zeros(adata.n_obs)
            X = np.stack([np.ravel(x), np.ravel(y)]).T
            V = np.stack([np.ravel(dx), np.ravel(dy)]).T
        else:
            x = None if X is None else X[:, 0]
            y = None if X is None else X[:, 1]
            X = _adata.obsm['X_' +
                            basis][:,
                                   get_components(components, basis, projection
                                                  )] if X is None else X[:, :2]
            V = _adata.obsm[vkey + '_' +
                            basis][:,
                                   get_components(components, basis, projection
                                                  )] if V is None else V[:, :2]

            hl, hw, hal = default_arrow(arrow_size)
            scale = 1 / arrow_length if arrow_length is not None else scale if scale is not None else 1
            quiver_kwargs.update({
                "scale": scale,
                "width": .0005,
                "headlength": hl,
                "headwidth": hw,
                "headaxislength": hal
            })

        for arg in list(kwargs):
            if arg in quiver_kwargs: quiver_kwargs.update({arg: kwargs[arg]})
            else: scatter_kwargs.update({arg: kwargs[arg]})

        if basis in adata.var_names and isinstance(
                color, str) and color in adata.layers.keys():
            c = interpret_colorkey(_adata, basis, color, perc)
        else:
            c = interpret_colorkey(_adata, color, layer, perc)

        if density is not None and 0 < density < 1:
            ix_choice = np.random.choice(_adata.n_obs,
                                         size=int(density * _adata.n_obs),
                                         replace=False)
            c = c[ix_choice] if len(c) == _adata.n_obs else c
            X = X[ix_choice]
            V = V[ix_choice]

        if projection == '3d' and X.shape[1] > 2 and V.shape[1] > 2:
            V, size = V / scale / 5, size / 10
            x0, x1, x2, v0, v1, v2 = X[:, 0], X[:, 1], X[:,
                                                         2], V[:,
                                                               0], V[:,
                                                                     1], V[:,
                                                                           2]
            quiver3d_kwargs = {
                "zorder": 3,
                "linewidth": .5,
                "arrow_length_ratio": .3
            }
            c = list(c) + [element for element in list(c) for _ in range(2)]
            if is_color_like(c[0]):
                ax.quiver(x0, x1, x2, v0, v1, v2, color=c, **quiver3d_kwargs)
            else:
                ax.quiver(x0, x1, x2, v0, v1, v2, c, **quiver3d_kwargs)
        else:
            if is_color_like(c[0]):
                ax.quiver(X[:, 0],
                          X[:, 1],
                          V[:, 0],
                          V[:, 1],
                          color=c,
                          zorder=3,
                          **quiver_kwargs)
            else:
                ax.quiver(X[:, 0],
                          X[:, 1],
                          V[:, 0],
                          V[:, 1],
                          c,
                          zorder=3,
                          **quiver_kwargs)

        ax = scatter(adata,
                     basis=basis,
                     x=x,
                     y=y,
                     vkey=vkey,
                     layer=layer,
                     color=color,
                     size=size,
                     title=title,
                     ax=ax,
                     zorder=0,
                     **scatter_kwargs)

        savefig_or_show(dpi=dpi, save=save, show=show)
        if not show: return ax
예제 #26
0
    def Distributions(self,distributions,datatype,labels,trajectory_index,linestyle,linewidth,colors,title,xlabel,ylabel,is_legend=True,legend_location='upper right',bin_size=1,histtype = 'step',orientation='vertical',multiplotting=False):    
        """        
        Plots the distributions of species and/or propensities
        
        Normed=False because the total probability is determined by summation not by integration.

        Input:
         - *distributions* (nested list)
         - *datatype* (list)
         - *labels* (list)
         - *trajectory_index* (integer)
         - *linestyle* (string)
         - *linewidth* (float)            
         - *colors* (list)
         - *title* (string)
         - *xlabel* (string)
         - *ylabel* (string)       
         - *is_legend* (boolean)
         - *legend_location* [default = 'upper right'] (string/integer)
         - *bin_size* (string) [default = 1]
         - *histtype* (string)) [default = 'step']
         - *orientation* (string) [default = 'vertical']
         - *multiplotting* (boolean) [default = False]
        """ 
        plt.figure(self.plotnum)
        datatype_indices = [labels.index(Id) for Id in datatype]     
        if len(datatype) == 1:
            j = trajectory_index
        else:
            j=0

        for i in datatype_indices:
            dat_min = distributions[i][0].min() 
            dat_max = distributions[i][0].max()
            n_bins = 1 + (dat_max-dat_min) /bin_size # Just take one trajectory as reference
            L_bin_edges = np.linspace(dat_min-bin_size/2.0,dat_max+bin_size/2.0,n_bins+1)                
         
            if colors == None:              
                if j >= len(self.colors):                  
                    j=0
            elif isinstance(colors,list):
                if j >= len(colors):
                    j=0
            elif isinstance(colors,str):
                colors = [colors]
                j=0         

            if colors == None:
                output = plt.hist(distributions[i][0],L_bin_edges,weights = distributions[i][1],ls = linestyle,lw = linewidth,color = self.colors[j],histtype = histtype,orientation=orientation,normed=False) 
            else:             
               if clr.is_color_like(colors[j]):             
                    output = plt.hist(distributions[i][0],L_bin_edges,weights = distributions[i][1],ls = linestyle,lw = linewidth,color = colors[j],histtype = histtype,orientation=orientation,normed=False)
               else:
                    print("*** WARNING ***: '{0}' is not recognized as a valid color code".format(colors[j]) )
                    output = plt.hist(distributions[i][0],L_bin_edges,weights = distributions[i][1],ls = linestyle,lw = linewidth,color = self.colors[j],histtype = histtype,orientation=orientation,normed=False)
                    colors = None
            j+=1
        if is_legend:
            plt.legend(datatype,numpoints=1,frameon=True,loc=legend_location)
        plt.title(title)
        if orientation.lower() == 'horizontal':
            plt.xlabel(ylabel)
            plt.ylabel(xlabel)   
            if multiplotting:
                plt.xticks([0,max(output[0])*1.1])             
        else:
            plt.xlabel(xlabel)
            plt.ylabel(ylabel)   
            if multiplotting:
                plt.yticks([0,max(output[0])*1.1])             
    def process_color(self,
                      param,
                      colormap_possible=False,
                      bed_rgb_possible=False,
                      colormap_only=False,
                      default_value_is_colormap=False):
        """
        Put a valid color/colormap in self.properties[param]
        Args:
            param: param to check/update the value
            colormap_possible: if the self.properties[param] can be a colormap
            bed_rgb_possible: if the self.properties[param] can be 'bed_rgb'
            colormap_only: if the self.properties[param] must be a colormap

        Returns:
            True if the self.properties[param] is a colormap
            False if the self.properties[param] is not a colormap

        """
        default_value = self.DEFAULTS_PROPERTIES[param]
        valid_color = None
        if bed_rgb_possible and self.properties[param] == 'bed_rgb':
            return False
        if mc.is_color_like(self.properties[param]):
            valid_color = self.properties[param]
        # It can be a tuple (for example (1, 0.88, 0.66666) would be a valid color):
        # Warning: (1, 0.88, 2./3) is not a valid color anymore
        elif self.properties[param][0] == '(':
            match = color_tuple.match(self.properties[param].replace(' ', ''))
            if match is not None:
                try:
                    custom_color = tuple([float(v) for v in match.groups()])
                except ValueError as e:
                    self.log.warning(f"*WARNING*: '{param}' for section"
                                     f" {self.properties['section_name']}"
                                     f" raised an error:\n{e}\n"
                                     f"{param} has "
                                     "been set to "
                                     f"{default_value}.\n")
                    valid_color = default_value
                else:
                    if mc.is_color_like(custom_color):
                        valid_color = custom_color
                    else:
                        self.log.warning(f"*WARNING*: '{param}' for section"
                                         f" {self.properties['section_name']}"
                                         " is not valid. "
                                         f"{param} has "
                                         "been set to "
                                         f"{default_value}.\n")
                        valid_color = default_value
            else:
                self.log.warning(f"*WARNING*: '{param}' for section"
                                 f" {self.properties['section_name']}"
                                 " is not well formatted (expected (r, g, b), "
                                 "with r,g,b values as float). "
                                 f"{param} has "
                                 "been set to "
                                 f"{default_value}.\n")
                valid_color = default_value

        if not colormap_possible:
            if valid_color is None:
                self.log.warning(f"*WARNING*: '{param}' for section"
                                 f" {self.properties['section_name']}"
                                 " is not valid. "
                                 f"{param} has "
                                 "been set to "
                                 f"{default_value}.\n")
                valid_color = default_value
            self.properties[param] = valid_color
            return False
        else:
            valid_colormap = None
            message = ""
            # We will try to process the color as a colormap
            # If someone what to use its own colormap,
            # he can specify the rgb values or color values:
            # For example:
            # colormap = ['white', (1, 0.88, 0.66), (1, 0.74, 0.25), (1, 0.5, 0), (1, 0.19, 0), (0.74, 0, 0), (0.35, 0, 0)]
            # Warning:
            # colormap = ['white', (1, 0.88, 2./3), (1, 0.74, 0.25), (1, 0.5, 0), (1, 0.19, 0), (0.74, 0, 0), (0.35, 0, 0)]
            # is not any more a valid color because of 2./3
            if self.properties[param][0] == '[':
                if self.properties[param][-1] == ']':
                    # We remove all space and quote
                    prepared_color_list = re.sub(" |\'|\"", "",
                                                 self.properties[param][1:-1])
                    # We extract individual colors
                    match = block_no_comma_outside_parenthesis.findall(
                        prepared_color_list)
                    if match is not None:
                        # We check the color which start with '(' are (r,g,b) with rgb as floats
                        if all([
                                color_tuple.match(v) is not None for v in match
                                if v[0] == '('
                        ]):
                            # We try to convert them as float:
                            try:
                                custom_colors = [
                                    tuple([
                                        float(v)
                                        for v in color_tuple.match(v).groups()
                                    ]) if v[0] == '(' else v for v in match
                                ]
                            except ValueError:
                                message = "some (r,g,b) values of the list could not be converted to float"
                            else:
                                try:
                                    valid_colormap = mc.LinearSegmentedColormap.from_list(
                                        'custom', custom_colors, N=100)
                                except ValueError:
                                    message = "the list of color could not be converted to colormap"
                        else:
                            message = "there is no color between brackets"
                    else:
                        message = "some colors starting with ( in the color" \
                                  " list are not formatted (r,g,b) with r,g,b as float"
                if message != "":
                    message = f" ({message})"
            else:
                if self.properties[param] in dir(plt.cm):
                    valid_colormap = self.properties[param]
        # Here, colormap is possible
        # valid_color is None or a valid color or the default value
        # valid_colormap is None or a valid colormap
        if valid_color is None and valid_colormap is None:
            self.log.warning(f"*WARNING* {param}: '{self.properties[param]}'"
                             f" for section {self.properties['section_name']}"
                             f" is not valid{message}. It has "
                             "been set to "
                             f"{default_value}.\n")
            self.properties[param] = default_value
            return default_value_is_colormap
        if colormap_only:
            if valid_colormap is None:
                # valid_color is not None
                self.log.warning(f"*WARNING* {param}: "
                                 f"'{self.properties[param]}' for section"
                                 f" {self.properties['section_name']}"
                                 f" is not valid{message}. It has "
                                 "been set to "
                                 f"{default_value}.\n")
                valid_colormap = default_value
            self.properties[param] = valid_colormap
            return True
        else:
            if valid_color is not None:
                self.properties[param] = valid_color
                return False
            else:
                self.properties[param] = valid_colormap
                return True
예제 #28
0
def add_cartesian_grid(ax,d):
    """
    Adds an overlaid cartesian coordinate grid over an image
    using the parameters in dictionary d.

    The dictionary d has required and optional parameters as follows:
        x0,y0           (req'd) the origin
        Nx,Ny           (req'd) the image extent
        space           (str) 'Q' or 'R'
        spacing         (number) spacing between gridlines
        pixelsize       (number)
        pixelunits      (str)
        lw              (number)
        ls              (str)
        color           (color)
        label           (bool)
        labelsize       (number)
        labelcolor      (color)
        alpha           (number)
    """
    # handle inputs
    assert isinstance(ax,Axes)
    # origin
    assert('x0' in d.keys())
    assert('y0' in d.keys())
    x0,y0 = d['x0'],d['y0']
    # image extent
    assert('Nx' in d.keys())
    assert('Ny' in d.keys())
    Nx,Ny = d['Nx'],d['Ny']
    assert x0<Nx and y0<Ny
    # real or diffraction
    space = d['space'] if 'space' in d.keys() else 'Q'
    assert(space in ('Q','R'))
    # spacing, pixelsize, pixelunits
    spacing = d['spacing'] if 'spacing' in d.keys() else None
    pixelsize = d['pixelsize'] if 'pixelsize' in d.keys() else 1
    pixelunits = d['pixelunits'] if 'pixelunits' in d.keys() else 'pixels'
    # gridlines
    lw = d['lw'] if 'lw' in d.keys() else 1
    ls = d['ls'] if 'ls' in d.keys() else ':'
    # color
    color = d['color'] if 'color' in d.keys() else 'w'
    assert is_color_like(color)
    # labels
    label = d['label'] if 'label' in d.keys() else False
    labelsize = d['labelsize'] if 'labelsize' in d.keys() else 12
    labelcolor = d['labelcolor'] if 'labelcolor' in d.keys() else 'k'
    assert isinstance(label,bool)
    assert isinstance(labelsize,Number)
    assert is_color_like(labelcolor)
    # alpha
    alpha = d['alpha'] if 'alpha' in d.keys() else 0.35
    assert isinstance(alpha,(Number))
    # additional parameters
    kws = [k for k in d.keys() if k not in ('x0','y0','spacing','lw','ls',
                        'color','label','labelsize','labelcolor','alpha')]
    kwargs = dict()
    for k in kws:
        kwargs[k] = d[k]

    # Get the major grid-square size
    if spacing is None:
        gridspacing,_,_gridspacing = get_nice_spacing(Nx,Ny,pixelsize)
    else:
        gridspacing,_gridspacing = spacing,1.5

    # Get positions for the major gridlines
    xmin = (-x0)*pixelsize
    xmax = (Nx-1-x0)*pixelsize
    ymin = (-y0)*pixelsize
    ymax = (Ny-1-y0)*pixelsize
    xticksmajor = np.concatenate((-1*np.arange(0,np.abs(xmin),gridspacing)[1:][::-1],
                                  np.arange(0,xmax,gridspacing)))
    yticksmajor = np.concatenate((-1*np.arange(0,np.abs(ymin),gridspacing)[1:][::-1],
                                  np.arange(0,ymax,gridspacing)))
    xticklabels = xticksmajor.copy()
    yticklabels = yticksmajor.copy()
    xticksmajor = (xticksmajor-xmin)/pixelsize
    yticksmajor = (yticksmajor-ymin)/pixelsize

    # Get labels
    exp_spacing = int(np.round(log(gridspacing,10),6))
    if np.sign(log(gridspacing,10))<0:
        exp_spacing-=1
    base_spacing = gridspacing/(10**exp_spacing)
    xticklabels = xticklabels/(10**exp_spacing)
    yticklabels = yticklabels/(10**exp_spacing)
    if exp_spacing == 1:
        xticklabels *= 10
        yticklabels *= 10
    if _gridspacing in (0.4,0.75,1.5,2.5) and exp_spacing!=1:
        xticklabels = ["{:.1f}".format(n) for n in xticklabels]
        yticklabels = ["{:.1f}".format(n) for n in yticklabels]
    else:
        xticklabels = ["{:.0f}".format(n) for n in xticklabels]
        yticklabels = ["{:.0f}".format(n) for n in yticklabels]

    # Add the grid
    ax.set_xticks(yticksmajor)
    ax.set_yticks(xticksmajor)
    ax.xaxis.set_ticks_position('bottom')
    if label:
        ax.set_xticklabels(yticklabels,size=labelsize,color=labelcolor)
        ax.set_yticklabels(xticklabels,size=labelsize,color=labelcolor)
        axislabel_x = r"$q_x$" if space=='Q' else r"$x$"
        axislabel_y = r"$q_y$" if space=='Q' else r"$y$"
        if exp_spacing in (0,1):
            ax.set_xlabel(axislabel_y+" ("+pixelunits+")",size=labelsize,color=labelcolor)
            ax.set_ylabel(axislabel_x+" ("+pixelunits+")",size=labelsize,color=labelcolor)
        else:
            ax.set_xlabel(axislabel_y+" ("+pixelunits+" e"+str(exp_spacing)+")",
                          size=labelsize,color=labelcolor)
            ax.set_ylabel(axislabel_x+" ("+pixelunits+" e"+str(exp_spacing)+")",
                          size=labelsize,color=labelcolor)
    else:
        ax.set_xticklabels([])
        ax.set_yticklabels([])
    ax.grid(linestyle=ls,linewidth=lw,color=color,alpha=alpha)

    return
예제 #29
0
def _plot_kmf_single(df,
                     condition_col,
                     survival_col,
                     censor_col,
                     threshold,
                     title,
                     xlabel,
                     ylabel,
                     ax,
                     with_condition_color,
                     no_condition_color,
                     with_condition_label,
                     no_condition_label,
                     color_map,
                     label_map,
                     color_palette,
                     ci_show,
                     print_as_title):
    """
    Helper function to produce a single KM survival plot, among observations in df by groups defined by condition_col.

    All inputs are required - this function is intended to be called by `plot_kmf`.
    """
    # make color inputs consistent hex format
    if colors.is_color_like(with_condition_color):
        with_condition_color = colors.to_hex(with_condition_color)
    if colors.is_color_like(no_condition_color):
        no_condition_color = colors.to_hex(no_condition_color)
    ## prepare data to be plotted; producing 3 outputs:
    # - `condition`, series containing category labels to be plotted
    # - `label_map` (mapping condition values to plot labels)
    # - `color_map` (mapping condition values to plotted colors)
    if threshold is not None:
        is_median = threshold == "median"
        if is_median:
            threshold = df[condition_col].median()
        label_suffix = float_str(threshold)
        condition = df[condition_col] > threshold
        default_label_no_condition = "%s ≤ %s" % (condition_col, label_suffix)
        if is_median:
            label_suffix += " (median)"
        default_label_with_condition = "%s > %s" % (condition_col, label_suffix)
        with_condition_label = with_condition_label or default_label_with_condition
        no_condition_label = no_condition_label or default_label_no_condition
        if not label_map:
            label_map = {False: no_condition_label,
                         True: with_condition_label}
        if not color_map:
            color_map = {False: no_condition_color,
                         True: with_condition_color}
    elif df[condition_col].dtype == 'O' or df[condition_col].dtype.name == "category":
        condition = df[condition_col].astype("category")
        if not label_map:
            label_map = dict()
            [label_map.update({condition_value: '{} = {}'.format(condition_col,
                                                        condition_value)})
                     for condition_value in condition.unique()]
        if not color_map:
            rgb_values = sb.color_palette(color_palette, len(label_map.keys()))
            hex_values = [colors.to_hex(col) for col in rgb_values]
            color_map = dict(zip(label_map.keys(), hex_values))
    elif df[condition_col].dtype == 'bool':
        condition = df[condition_col]
        default_label_with_condition = "= {}".format(condition_col)
        default_label_no_condition = "¬ {}".format(condition_col)
        with_condition_label = with_condition_label or default_label_with_condition
        no_condition_label = no_condition_label or default_label_no_condition
        if not label_map:
            label_map = {False: no_condition_label,
                         True: with_condition_label}
        if not color_map:
            color_map = {False: no_condition_color,
                         True: with_condition_color}
    else:
        raise ValueError('Don\'t know how to plot data of type\
                         {}'.format(df[condition_col].dtype))

    # produce kmf plot for each category (group) identified above
    kmf = KaplanMeierFitter()
    grp_desc = list()
    grp_survival_data = dict()
    grp_event_data = dict()
    grp_names = list(condition.unique())
    for grp_name, grp_df in df.groupby(condition):
        grp_survival = grp_df[survival_col]
        grp_event = (grp_df[censor_col].astype(bool))
        grp_label = label_map[grp_name]
        grp_color = color_map[grp_name]
        kmf.fit(grp_survival, grp_event, label=grp_label)
        desc_str = "# {}: {}".format(grp_label, len(grp_survival))
        grp_desc.append(desc_str)
        grp_survival_data[grp_name] = grp_survival
        grp_event_data[grp_name] = grp_event
        if ax:
            ax = kmf.plot(ax=ax, show_censors=True, ci_show=ci_show, color=grp_color)
        else:
            ax = kmf.plot(show_censors=True, ci_show=ci_show, color=grp_color)

    ## format the plot
    # Set the y-axis to range 0 to 1
    ax.set_ylim(0, 1)
    y_tick_vals = ax.get_yticks()
    ax.set_yticklabels(["%d" % int(y_tick_val * 100) for y_tick_val in y_tick_vals])
    # plot title
    if title:
        ax.set_title(title)
    elif print_as_title:
        ax.set_title(' | '.join(grp_desc))
    else:
        [print(desc) for desc in grp_desc]
    # axis labels
    if xlabel:
        ax.set_xlabel(xlabel)
    if ylabel:
        ax.set_ylabel(ylabel)
    
    ## summarize analytical version of results
    ## again using same groups as are plotted
    if len(grp_names) == 2:
        # use log-rank test for 2 groups
        results = logrank_test(grp_survival_data[grp_names[0]],
                               grp_survival_data[grp_names[1]],
                               event_observed_A=grp_event_data[grp_names[0]],
                               event_observed_B=grp_event_data[grp_names[1]])
    elif len(grp_names) == 1:
        # no analytical result for 1 or 0 groups
        results = NullSurvivalResults()
    else:
        # cox PH fitter for >2 groups
        cf = CoxPHFitter()
        cox_df = patsy.dmatrix('+'.join([condition_col, survival_col,
                                         censor_col]),
                               df, return_type='dataframe')
        del cox_df['Intercept']
        results = cf.fit(cox_df, survival_col, event_col=censor_col)
        results.print_summary()
    # add metadata to results object so caller can print them
    results.survival_data_series = grp_survival_data
    results.event_data_series = grp_event_data
    results.desc = grp_desc
    return results
예제 #30
0
def add_polarelliptical_grid(ax,d):
    """
    adds an overlaid polar-ellitpical coordinate grid over an image
    using the parameters in dictionary d.

    The dictionary d has required and optional parameters as follows:
        x0,y0           (req'd) the origin
        e,theta         (req'd) the ellipticity (a/b) and major axis angle (radians)
        Nx,Ny           (req'd) the image extent
        space           (str) 'Q' or 'R'
        spacing         (number) spacing between radial gridlines
        N_thetalines    (int) the number of theta gridlines
        pixelsize       (number)
        pixelunits      (str)
        lw              (number)
        ls              (str)
        color           (color)
        label           (bool)
        labelsize       (number)
        labelcolor      (color)
        alpha           (number)
    """
    # handle inputs
    assert isinstance(ax,Axes)
    # origin
    assert('x0' in d.keys())
    assert('y0' in d.keys())
    x0,y0 = d['x0'],d['y0']
    # ellipticity
    assert('e' in d.keys())
    assert('theta' in d.keys())
    e,theta = d['e'],d['theta']
    # image extent
    assert('Nx' in d.keys())
    assert('Ny' in d.keys())
    Nx,Ny = d['Nx'],d['Ny']
    assert x0<Nx and y0<Ny
    # real or diffraction
    space = d['space'] if 'space' in d.keys() else 'Q'
    assert(space in ('Q','R'))
    # spacing, N_thetalines, pixelsize, pixelunits
    spacing = d['spacing'] if 'spacing' in d.keys() else None
    N_thetalines = d['N_thetalines'] if 'N_thetalines' in d.keys() else 8
    assert(N_thetalines%2==0), "N_thetalines must be even"
    N_thetalines = N_thetalines//2
    assert isinstance(N_thetalines,(int,np.integer))
    pixelsize = d['pixelsize'] if 'pixelsize' in d.keys() else 1
    pixelunits = d['pixelunits'] if 'pixelunits' in d.keys() else 'pixels'
    # gridlines
    lw = d['lw'] if 'lw' in d.keys() else 1
    ls = d['ls'] if 'ls' in d.keys() else ':'
    # color
    color = d['color'] if 'color' in d.keys() else 'w'
    assert is_color_like(color)
    # labels
    label = d['label'] if 'label' in d.keys() else False
    labelsize = d['labelsize'] if 'labelsize' in d.keys() else 8
    labelcolor = d['labelcolor'] if 'labelcolor' in d.keys() else color
    assert isinstance(label,bool)
    assert isinstance(labelsize,Number)
    assert is_color_like(labelcolor)
    # alpha
    alpha = d['alpha'] if 'alpha' in d.keys() else 0.5
    assert isinstance(alpha,(Number))
    # additional parameters
    kws = [k for k in d.keys() if k not in ('x0','y0','spacing','lw','ls',
                        'color','label','labelsize','labelcolor','alpha')]
    kwargs = dict()
    for k in kws:
        kwargs[k] = d[k]

    # Get the radial spacing
    if spacing is None:
        spacing,_,_spacing = get_nice_spacing(Nx,Ny,pixelsize)
        spacing = spacing/2.
    else:
        _spacing = 1.5

    # Get positions for the radial gridlines
    xmin = (-x0)*pixelsize
    xmax = (Nx-1-x0)*pixelsize
    ymin = (-y0)*pixelsize
    ymax = (Ny-1-y0)*pixelsize
    rcorners = (np.hypot(xmin,ymin),
               np.hypot(xmin,ymax),
               np.hypot(xmax,ymin),
               np.hypot(xmax,ymax))
    rticks = np.arange(0,np.max(rcorners),spacing)[1:]
    rticklabels = rticks.copy()
    rticks = rticks/pixelsize

    # Add radial gridlines
    N = len(rticks)
    d_ellipses = {'a':list(rticks),
                  'center':(x0,y0),
                  'e':e,
                  'theta':theta,
                  'fill':False,
                  'color':color,
                  'linewidth':lw,
                  'linestyle':ls,
                  'alpha':alpha}
    add_ellipses(ax,d_ellipses)

    # Add radial gridline labels
    if label:
        # Get gridline label positions
        rlabelpos_scale = 1+ (e-1)*np.sin(np.pi/2-theta)**4
        rlabelpositions = x0 - rticks*rlabelpos_scale
        for i in range(len(rticklabels)):
            xpos = rlabelpositions[i]
            if xpos>labelsize/2:
                ax.text(y0,rlabelpositions[i],rticklabels[i],size=labelsize,
                color=labelcolor,alpha=alpha,ha='center',va='center')

    # Add theta gridlines
    def add_line(ax,x0,y0,theta,Nx,Ny):
        """ adds a line through (x0,y0) at an angle theta which terminates at the image edges
            returns the termination points (xi,yi),(xf,xy)
        """
        theta = np.mod(np.pi/2-theta,np.pi)
        if theta==0:
            xs,ys = [0,Nx-1],[y0,y0]
        elif theta==np.pi/2:
            xs,ys = [x0,x0],[0,Ny-1]
        else:
            # Get line params
            m = np.tan(theta)
            b = y0-m*x0
            # Get intersections with x=0,x=Nx-1,y=0,y=Ny-1
            x1,y1 = 0,b
            x2,y2 = Nx-1,m*(Nx-1)+b
            x3,y3 = -b/m,0
            x4,y4 = (Ny-1 -b)/m,Ny-1
            # Determine which points are on the image bounding box
            xs,ys = [],[]
            if 0<=y1<Ny-1: xs.append(x1),ys.append(y1)
            if 0<=y2<Ny-1: xs.append(x2),ys.append(y2)
            if 0<=x3<Nx-1: xs.append(x3),ys.append(y3)
            if 0<=x4<Nx-1: xs.append(x4),ys.append(y4)
            assert len(xs)==len(ys)==2

        ax.plot(xs,ys,color=color,ls=ls,alpha=alpha,lw=lw)
        return tuple([(xs[i],ys[i]) for i in range(2)])

    thetalabelpos = []
    for t in theta+np.linspace(0,np.pi,N_thetalines,endpoint=False):
        thetalabelpos.append(add_line(ax,x0,y0,t,Nx,Ny))
    thetalabelpos = [thetalabelpos[i][0] for i in range(len(thetalabelpos))] + \
                    [thetalabelpos[i][1] for i in range(len(thetalabelpos))]
    # Get angles for the theta gridlines
    thetaticklabels = [str(Fraction(i,N_thetalines))+r'$\pi$' for i in range(2*N_thetalines)]
    thetaticklabels[0] = '0'
    thetaticklabels[N_thetalines] = r'$\pi$'

    # Add theta gridline labels
    if label:
        for i in range(len(thetaticklabels)):
            x,y = thetalabelpos[i]
            if x==0: ha,va='left','center'
            elif x==Nx-1: ha,va='right','center'
            elif y==0: ha,va='center','top'
            else: ha,va='center','bottom'
            ax.text(x,y,thetaticklabels[i],size=labelsize,color=labelcolor,
                    alpha=alpha,ha=ha,va=va)
        pass

    ax.set_xticks([])
    ax.set_yticks([])
    ax.set_xlim([0,Nx-1])
    ax.set_ylim([0,Ny-1])
    ax.invert_yaxis()
    return
예제 #31
0
파일: paga.py 프로젝트: terooatt/scanpy
def _paga_graph(adata,
                ax,
                solid_edges=None,
                dashed_edges=None,
                threshold_solid=None,
                threshold_dashed=1e-6,
                root=0,
                rootlevel=None,
                color=None,
                groups=None,
                fontsize=None,
                node_size_scale=1,
                node_size_power=0.5,
                edge_width_scale=1,
                title=None,
                layout=None,
                pos=None,
                cmap=None,
                frameon=True,
                min_edge_width=None,
                max_edge_width=None,
                export_to_gexf=False,
                random_state=0):
    node_labels = groups
    if (node_labels is not None and isinstance(node_labels, str)
            and node_labels != adata.uns['paga']['groups']):
        raise ValueError(
            'Provide a list of group labels for the PAGA groups {}, not {}.'.
            format(adata.uns['paga']['groups'], node_labels))
    groups_key = adata.uns['paga']['groups']
    if node_labels is None:
        node_labels = adata.obs[groups_key].cat.categories

    if color is None and groups_key is not None:
        if (groups_key + '_colors' not in adata.uns
                or len(adata.obs[groups_key].cat.categories) != len(
                    adata.uns[groups_key + '_colors'])):
            utils.add_colors_for_categorical_sample_annotation(
                adata, groups_key)
        color = adata.uns[groups_key + '_colors']
        for iname, name in enumerate(adata.obs[groups_key].cat.categories):
            if name in settings.categories_to_ignore: color[iname] = 'grey'

    if isinstance(root, str):
        if root in node_labels:
            root = list(node_labels).index(root)
        else:
            raise ValueError(
                'If `root` is a string, it needs to be one of {} not \'{}\'.'.
                format(node_labels.tolist(), root))
    if isinstance(root, list) and root[0] in node_labels:
        root = [list(node_labels).index(r) for r in root]

    # define the objects
    adjacency_solid = adata.uns['paga'][solid_edges].copy()
    if threshold_solid is not None:
        adjacency_solid[adjacency_solid < threshold_solid] = 0
    nx_g_solid = nx.Graph(adjacency_solid)
    if dashed_edges is not None:
        adjacency_dashed = adata.uns['paga'][dashed_edges].copy()
        if threshold_dashed is not None:
            adjacency_dashed[adjacency_dashed < threshold_dashed] = 0
        nx_g_dashed = nx.Graph(adjacency_dashed)

    # degree of the graph for coloring
    if isinstance(color, str) and color.startswith('degree'):
        # see also tools.paga.paga_degrees
        if color == 'degree_dashed':
            color = [d for _, d in nx_g_dashed.degree(weight='weight')]
        elif color == 'degree_solid':
            color = [d for _, d in nx_g_solid.degree(weight='weight')]
        else:
            raise ValueError(
                '`degree` either "degree_dashed" or "degree_solid".')
        color = (np.array(color) - np.min(color)) / (np.max(color) -
                                                     np.min(color))

    # plot numeric colors
    colorbar = False
    if isinstance(
            color,
        (list, np.ndarray)) and not isinstance(color[0], (str, dict)):
        import matplotlib
        norm = matplotlib.colors.Normalize()
        color = norm(color)
        if cmap is None: cmap = rcParams['image.cmap']
        cmap = matplotlib.cm.get_cmap(cmap)
        color = [cmap(c) for c in color]
        colorbar = True

    if len(color) < len(node_labels):
        print(node_labels, color)
        raise ValueError(
            '`color` list need to be at least as long as `node_labels` list.')

    # node positions from adjacency_solid
    if pos is None:
        if layout is None:
            layout = 'fr'
        # igraph layouts
        if layout != 'eq_tree':
            from ... import utils as sc_utils
            adj_solid_weights = adjacency_solid
            g = sc_utils.get_igraph_from_adjacency(adj_solid_weights)
            if 'rt' in layout:
                g_tree = g
                if solid_edges != 'confidence_tree':
                    adj_tree = adata.uns['paga']['confidence_tree']
                    g_tree = sc_utils.get_igraph_from_adjacency(adj_tree)
                pos_list = g_tree.layout(
                    layout,
                    root=root if isinstance(root, list) else [root],
                    rootlevel=rootlevel).coords
            elif layout == 'circle':
                pos_list = g.layout(layout).coords
            else:
                np.random.seed(random_state)
                init_coords = np.random.random(
                    (adjacency_solid.shape[0], 2)).tolist()
                pos_list = g.layout(layout, seed=init_coords,
                                    weights='weight').coords
            pos = {n: [p[0], -p[1]] for n, p in enumerate(pos_list)}
        # equally-spaced tree
        else:
            nx_g_tree = nx_g_solid
            if solid_edges != 'confidence_tree':
                adj_tree = adata.uns['paga']['confidence_tree']
                nx_g_tree = nx.Graph(adj_tree)
            pos = utils.hierarchy_pos(nx_g_tree, root)
            if len(pos) < adjacency_solid.shape[0]:
                raise ValueError('This is a forest and not a single tree. '
                                 'Try another `layout`, e.g., {\'fr\'}.')
        pos_array = np.array([pos[n] for count, n in enumerate(nx_g_solid)])
    else:
        if isinstance(pos, str):
            if not pos.endswith('.gdf'):
                raise ValueError(
                    'Currently only supporting reading positions from .gdf files.'
                    'Consider generating them using, for instance, Gephi.')
            s = ''  # read the node definition from the file
            with open(pos) as f:
                f.readline()
                for line in f:
                    if line.startswith('edgedef>'):
                        break
                    s += line
            from io import StringIO
            df = pd.read_csv(StringIO(s), header=-1)
            pos = df[[4, 5]].values
        pos_array = pos
        # convert to dictionary
        pos = {n: [p[0], p[1]] for n, p in enumerate(pos)}

    if len(pos) == 1: pos[0] = (0.5, 0.5)

    # edge widths
    base_edge_width = edge_width_scale * 5 * rcParams['lines.linewidth']

    # draw dashed edges
    if dashed_edges is not None:
        widths = [x[-1]['weight'] for x in nx_g_dashed.edges(data=True)]
        widths = base_edge_width * np.array(widths)
        if max_edge_width is not None:
            widths = np.clip(widths, None, max_edge_width)
        nx.draw_networkx_edges(nx_g_dashed,
                               pos,
                               ax=ax,
                               width=widths,
                               edge_color='grey',
                               style='dashed',
                               alpha=0.5)

    # draw solid edges
    widths = [x[-1]['weight'] for x in nx_g_solid.edges(data=True)]
    widths = base_edge_width * np.array(widths)
    if min_edge_width is not None or max_edge_width is not None:
        widths = np.clip(widths, min_edge_width, max_edge_width)
    nx.draw_networkx_edges(nx_g_solid,
                           pos,
                           ax=ax,
                           width=widths,
                           edge_color='black')

    if export_to_gexf:
        for count, n in enumerate(nx_g_solid.nodes()):
            nx_g_solid.node[count]['label'] = node_labels[count]
            nx_g_solid.node[count]['color'] = color[count]
            nx_g_solid.node[count]['viz'] = {
                'position': {
                    'x': 1000 * pos[count][0],
                    'y': 1000 * pos[count][1],
                    'z': 0
                }
            }
        logg.msg('exporting to {}'.format(settings.writedir +
                                          'paga_graph.gexf'),
                 v=1)
        nx.write_gexf(nx_g_solid, settings.writedir + 'paga_graph.gexf')

    # deal with empty graph
    # ax.plot(pos_array[:, 0], pos_array[:, 1], '.', c='white')

    # draw the nodes (pie charts)
    trans = ax.transData.transform
    bbox = ax.get_position().get_points()
    ax_x_min = bbox[0, 0]
    ax_x_max = bbox[1, 0]
    ax_y_min = bbox[0, 1]
    ax_y_max = bbox[1, 1]
    ax_len_x = ax_x_max - ax_x_min
    ax_len_y = ax_y_max - ax_y_min
    # print([ax_x_min, ax_x_max, ax_y_min, ax_y_max])
    # print([ax_len_x, ax_len_y])
    trans2 = ax.transAxes.inverted().transform
    ax.set_frame_on(frameon)
    ax.set_xticks([])
    ax.set_yticks([])
    if (groups_key is not None and groups_key + '_sizes' in adata.uns):
        groups_sizes = adata.uns[groups_key + '_sizes']
    else:
        groups_sizes = np.ones(len(node_labels))
    base_scale_scatter = 2000
    base_pie_size = (base_scale_scatter /
                     (np.sqrt(adjacency_solid.shape[0]) + 10) *
                     node_size_scale)
    median_group_size = np.median(groups_sizes)
    groups_sizes = base_pie_size * np.power(groups_sizes / median_group_size,
                                            node_size_power)
    # usual scatter plot
    if is_color_like(color[0]):
        ax.scatter(pos_array[:, 0],
                   pos_array[:, 1],
                   c=color,
                   edgecolors='face',
                   s=groups_sizes)
        for count, group in enumerate(node_labels):
            ax.text(pos_array[count, 0],
                    pos_array[count, 1],
                    group,
                    verticalalignment='center',
                    horizontalalignment='center',
                    size=fontsize)
    # else pie chart plot
    else:
        force_labels_to_front = True  # TODO: solve this differently!
        for count, n in enumerate(nx_g_solid.nodes()):
            pie_size = groups_sizes[count] / base_scale_scatter
            xx, yy = trans(pos[n])  # data coordinates
            xa, ya = trans2((xx, yy))  # axis coordinates
            xa = ax_x_min + (xa - pie_size / 2) * ax_len_x
            ya = ax_y_min + (ya - pie_size / 2) * ax_len_y
            # clip, the fruchterman layout sometimes places below figure
            if ya < 0: ya = 0
            if xa < 0: xa = 0
            a = pl.axes([xa, ya, pie_size * ax_len_x, pie_size * ax_len_y])
            if not isinstance(color[count], dict):
                raise ValueError(
                    '{} is neither a dict of valid matplotlib colors '
                    'nor a valid matplotlib color.'.format(color[count]))
            color_single = color[count].keys()
            fracs = [color[count][c] for c in color_single]
            if sum(fracs) < 1:
                color_single = list(color_single)
                color_single.append('grey')
                fracs.append(1 - sum(fracs))
            a.pie(fracs, colors=color_single)
            if not force_labels_to_front and node_labels is not None:
                a.text(0.5,
                       0.5,
                       node_labels[count],
                       verticalalignment='center',
                       horizontalalignment='center',
                       transform=a.transAxes,
                       size=fontsize)
        # TODO: this is a terrible hack, but if we use the solution above (`not
        # force_labels_to_front`), labels get hidden behind pies
        if force_labels_to_front and node_labels is not None:
            for count, n in enumerate(nx_g_solid.nodes()):
                pie_size = groups_sizes[count] / base_scale_scatter
                # all copy and paste from above
                xx, yy = trans(pos[n])  # data coordinates
                xa, ya = trans2((xx, yy))  # axis coordinates
                # make sure a new axis is created
                xa = ax_x_min + (xa - pie_size / 2.0000001) * ax_len_x
                ya = ax_y_min + (ya - pie_size / 2.0000001) * ax_len_y
                # clip, the fruchterman layout sometimes places below figure
                if ya < 0: ya = 0
                if xa < 0: xa = 0
                a = pl.axes([xa, ya, pie_size * ax_len_x, pie_size * ax_len_y])
                a.set_frame_on(False)
                a.set_xticks([])
                a.set_yticks([])
                a.text(0.5,
                       0.5,
                       node_labels[count],
                       verticalalignment='center',
                       horizontalalignment='center',
                       transform=a.transAxes,
                       size=fontsize)
    if title is not None: ax.set_title(title)
    if colorbar:
        ax1 = pl.axes([0.95, 0.1, 0.03, 0.7])
        cb = matplotlib.colorbar.ColorbarBase(ax1, cmap=cmap, norm=norm)
    return pos_array
예제 #32
0
def _scatter_obs(
        adata,
        x=None,
        y=None,
        color=None,
        use_raw=True,
        sort_order=True,
        alpha=None,
        basis=None,
        groups=None,
        components=None,
        projection='2d',
        legend_loc='right margin',
        legend_fontsize=None,
        legend_fontweight=None,
        color_map=None,
        palette=None,
        right_margin=None,
        left_margin=None,
        size=None,
        title=None,
        show=None,
        save=None,
        ax=None):
    """Scatter plot.

    Color with annotation of observations (`.obs`) or expression of genes
    (`.var_names`).

    Parameters
    ----------
    adata : :class:`~scanpy.api.AnnData`
        Annotated data matrix.
    x : `str` or `None`
        x coordinate.
    y : `str` or `None`
        y coordinate.
    color : string or list of strings, optional (default: `None`)
        Keys for observation/cell annotation `[\'ann1\', \'ann2\']`.
    use_raw : `bool`, optional (default: `True`)
        Use `raw` attribute of `adata` if present.
    sort_order : `bool`, optional (default: `True`)
        For continuous annotations used as color parameter, plot data points
        with higher values on top of others.
    basis : {'pca', 'tsne', 'umap', 'diffmap', 'draw_graph_fr', etc.}
        String that denotes a plotting tool that computed coordinates.
    groups : `str`, optional (default: all groups in color)
        Allows to restrict categories in observation annotation to a subset.
    components : `str` or list of `str`, optional (default: '1,2')
         String of the form '1,2' or ['1,2', '2,3'].
    projection : {'2d', '3d'}, optional (default: '2d')
         Projection of plot.
    legend_loc : `str`, optional (default: 'right margin')
         Location of legend, either 'none', 'on data', 'right margin' or valid
         keywords for `matplotlib.pyplot.legend
         <https://matplotlib.org/api/_as_gen/matplotlib.pyplot.legend.html>`_.
         If 'on data export', the positions are exported to a text file.
    legend_fontsize : `int` (default: `None`)
         Legend font size.
    legend_fontweight : {'normal', 'bold', ...} (default: `None`)
         Legend font weight. Defaults to 'bold' if `legend_loc = 'on data'`,
         otherwise to 'normal'. Available are `['light', 'normal', 'medium',
         'semibold', 'bold', 'heavy', 'black']`.
    color_map : `str` (default: 'RdBu_r')
         String denoting matplotlib color map for continuous coloring.
    palette : list of `str` (default: `None`)
         Colors to use for plotting groups (categorical annotation).
    right_margin : `float` (default: 0.3)
         Adjust how far the plotting panel extends to the right.
    size : float (default: None)
         Point size. Observation-number dependent by default.
    title : `str` or list of `str`, optional (default: `None`)
         Provide title for panels either as `[\'title1\', ...]`.
    show : `bool`, optional (default: `None`)
         Show the plot.
    save : `bool` or `str`, optional (default: `None`)
        If `True` or a `str`, save the figure. A string is appended to the
        default filename. Infer the filetype if ending on \{'.pdf', '.png', '.svg'\}.
    ax : `matplotlib.Axes`
         A `matplotlib.Axes` object.

    Returns
    -------
    If `show==False` a `matplotlib.Axis` or a list of it.
    """
    sanitize_anndata(adata)
    if legend_loc not in VALID_LEGENDLOCS:
        raise ValueError(
            'Invalid `legend_loc`, needs to be one of: {}.'.format(VALID_LEGENDLOCS))
    if components is None: components = '1,2' if '2d' in projection else '1,2,3'
    if isinstance(components, str): components = components.split(',')
    components = np.array(components).astype(int) - 1
    keys = ['grey'] if color is None else [color] if isinstance(color, str) else color
    if title is not None and isinstance(title, str):
        title = [title]
    highlights = adata.uns['highlights'] if 'highlights' in adata.uns else []
    if basis is not None:
        try:
            # ignore the '0th' diffusion component
            if basis == 'diffmap': components += 1
            Y = adata.obsm['X_' + basis][:, components]
            # correct the component vector for use in labeling etc.
            if basis == 'diffmap': components -= 1
        except KeyError:
            raise KeyError('compute coordinates using visualization tool {} first'
                           .format(basis))
    elif x is not None and y is not None:
        if x in adata.obs and y in adata.obs:
            x_arr = adata._get_obs_array(x)
            y_arr = adata._get_obs_array(y)
            Y = np.c_[x_arr[:, None], y_arr[:, None]]
        elif x in adata.var and y in adata.var:
            x_arr = adata._get_var_array(x)
            y_arr = adata._get_var_array(y)
            Y = np.c_[x_arr[:, None], y_arr[:, None]]
        else:
            raise ValueError('`x` and `y` variables must both be ins `.obs` or both be in `.var`!')
    else:
        raise ValueError('Either provide a `basis` or `x` and `y`.')

    if size is None:
        n = Y.shape[0]
        size = 120000 / n

    if legend_loc.startswith('on data') and legend_fontsize is None:
        legend_fontsize = rcParams['legend.fontsize']
    elif legend_fontsize is None:
        legend_fontsize = rcParams['legend.fontsize']

    palette_was_none = False
    if palette is None: palette_was_none = True
    if isinstance(palette, list):
        if not is_color_like(palette[0]):
            palettes = palette
        else:
            palettes = [palette]
    else:
        palettes = [palette for i in range(len(keys))]
    for i, palette in enumerate(palettes):
        palettes[i] = utils.default_palette(palette)

    if basis is not None:
        component_name = (
            'DC' if basis == 'diffmap'
            else 'tSNE' if basis == 'tsne'
            else 'UMAP' if basis == 'umap'
            else 'PC' if basis == 'pca'
            else basis.replace('draw_graph_', '').upper() if 'draw_graph' in basis
            else basis)
    else:
        component_name = None
    axis_labels = (x, y) if component_name is None else None
    show_ticks = True if component_name is None else False

    # the actual color ids, e.g. 'grey' or '#109482'
    color_ids = [None if not is_color_like(key)
                 else key for key in keys]
    categoricals = []
    colorbars = []
    for ikey, key in enumerate(keys):
        if color_ids[ikey] is not None:
            c = color_ids[ikey]
            continuous = True
            categorical = False
            colorbars.append(False)
        else:
            c = 'white' if projection == '2d' else 'white'
            categorical = False
            continuous = False
            # test whether we have categorial or continuous annotation
            if key in adata.obs_keys():
                if is_categorical_dtype(adata.obs[key]):
                    categorical = True
                else:
                    continuous = True
                    c = adata.obs[key]
            # coloring according to gene expression
            elif (use_raw
                  and adata.raw is not None
                  and key in adata.raw.var_names):
                c = adata.raw[:, key].X
                continuous = True
            elif key in adata.var_names:
                c = adata[:, key].X
                continuous = True
            else:
                raise ValueError(
                    'key \'{}\' is invalid! pass valid observation annotation, '
                    'one of {} or a gene name {}'
                    .format(key, adata.obs_keys(), adata.var_names))
            colorbars.append(True if continuous else False)
        if categorical: categoricals.append(ikey)
        color_ids[ikey] = c

    if right_margin is None and len(categoricals) > 0:
        if legend_loc == 'right margin': right_margin = 0.5
    if title is None and keys[0] is not None:
        title = [key.replace('_', ' ') if not is_color_like(key) else '' for key in keys]

    axs = scatter_base(Y,
                       title=title,
                       alpha=alpha,
                       component_name=component_name,
                       axis_labels=axis_labels,
                       component_indexnames=components + 1,
                       projection=projection,
                       colors=color_ids,
                       highlights=highlights,
                       colorbars=colorbars,
                       right_margin=right_margin,
                       left_margin=left_margin,
                       sizes=[size for c in keys],
                       color_map=color_map,
                       show_ticks=show_ticks,
                       ax=ax)

    def add_centroid(centroids, name, Y, mask):
        Y_mask = Y[mask]
        if Y_mask.shape[0] == 0: return
        median = np.median(Y_mask, axis=0)
        i = np.argmin(np.sum(np.abs(Y_mask - median), axis=1))
        centroids[name] = Y_mask[i]

    for i, ikey in enumerate(categoricals):
        palette = palettes[i]
        key = keys[ikey]
        utils.add_colors_for_categorical_sample_annotation(adata, key, palette)
        # actually plot the groups
        mask_remaining = np.ones(Y.shape[0], dtype=bool)
        centroids = {}
        if groups is None:
            for iname, name in enumerate(adata.obs[key].cat.categories):
                if name not in settings.categories_to_ignore:
                    mask = scatter_group(axs[ikey], key, iname,
                                         adata, Y, projection, size=size, alpha=alpha)
                    mask_remaining[mask] = False
                    if legend_loc.startswith('on data'): add_centroid(centroids, name, Y, mask)
        else:
            for name in groups:
                if name not in set(adata.obs[key].cat.categories):
                    raise ValueError('"' + name + '" is invalid!'
                                     + ' specify valid name, one of '
                                     + str(adata.obs[key].cat.categories))
                else:
                    iname = np.flatnonzero(adata.obs[key].cat.categories.values == name)[0]
                    mask = scatter_group(axs[ikey], key, iname,
                                         adata, Y, projection, size=size, alpha=alpha)
                    if legend_loc.startswith('on data'): add_centroid(centroids, name, Y, mask)
                    mask_remaining[mask] = False
        if mask_remaining.sum() > 0:
            data = [Y[mask_remaining, 0], Y[mask_remaining, 1]]
            if projection == '3d': data.append(Y[mask_remaining, 2])
            axs[ikey].scatter(*data, marker='.', c='grey', s=size,
                                    edgecolors='none', zorder=-1)
        legend = None
        if legend_loc.startswith('on data'):
            if legend_fontweight is None:
                legend_fontweight = 'bold'
            for name, pos in centroids.items():
                axs[ikey].text(pos[0], pos[1], name,
                               weight=legend_fontweight,
                               verticalalignment='center',
                               horizontalalignment='center',
                               fontsize=legend_fontsize)
            if legend_loc == 'on data export':
                all_pos = np.zeros((len(centroids), 2))
                for iname, name in enumerate(adata.obs[key].cat.categories):
                    all_pos[iname] = centroids[name]
                filename = settings.writedir + 'pos.csv'
                logg.msg('exporting label positions to {}'.format(filename), v=1)
                if settings.writedir != '' and not os.path.exists(settings.writedir):
                    os.makedirs(settings.writedir)
                np.savetxt(filename, all_pos, delimiter=',')
        elif legend_loc == 'right margin':
            legend = axs[ikey].legend(frameon=False, loc='center left',
                                            bbox_to_anchor=(1, 0.5),
                                            ncol=(1 if len(adata.obs[key].cat.categories) <= 14
                                                  else 2 if len(adata.obs[key].cat.categories) <= 30 else 3),
                                            fontsize=legend_fontsize)
        elif legend_loc != 'none':
            legend = axs[ikey].legend(frameon=False, loc=legend_loc,
                                            fontsize=legend_fontsize)
        if legend is not None:
            for handle in legend.legendHandles: handle.set_sizes([300.0])
    utils.savefig_or_show('scatter' if basis is None else basis, show=show, save=save)
    if show == False: return axs if len(keys) > 1 else axs[0]
예제 #33
0
def _set_colors_for_categorical_obs(adata, value_to_plot, palette):
    """
    Sets the adata.uns[value_to_plot + '_colors'] according to the given palette

    Parameters
    ----------
    adata : annData object
    value_to_plot : name of a valid categorical observation
    palette : Palette should be either a valid `matplotlib.pyplot.colormaps()` string,
              a list of colors (in a format that can be understood by matplotlib,
              eg. RGB, RGBS, hex, or a cycler object with key='color'

    Returns
    -------
    None
    """
    from matplotlib.colors import to_hex
    from cycler import Cycler, cycler

    categories = adata.obs[value_to_plot].cat.categories
    # check is palette is a valid matplotlib colormap
    if isinstance(palette, str) and palette in pl.colormaps():
        # this creates a palette from a colormap. E.g. 'Accent, Dark2, tab20'
        cmap = pl.get_cmap(palette)
        colors_list = [
            to_hex(x) for x in cmap(np.linspace(0, 1, len(categories)))
        ]

    else:
        # check if palette is a list and convert it to a cycler, thus
        # it doesnt matter if the list is shorter than the categories length:
        if isinstance(palette, list):
            if len(palette) < len(categories):
                logg.warn(
                    "Length of palette colors is smaller than the number of "
                    "categories (palette length: {}, categories length: {}. "
                    "Some categories will have the same color.".format(
                        len(palette), len(categories)))
            # check that colors are valid
            _color_list = []
            for color in palette:
                if not is_color_like(color):
                    # check if the color is a valid R color and translate it
                    # to a valid hex color value
                    if color in utils.additional_colors:
                        color = utils.additional_colors[color]
                    else:
                        raise ValueError(
                            "The following color value of the given palette is not valid: {}"
                            .format(color))
                _color_list.append(color)

            palette = cycler(color=_color_list)
        if not isinstance(palette, Cycler):
            raise ValueError(
                "Please check that the value of 'palette' is a "
                "valid matplotlib colormap string (eg. Set2), a "
                "list of color names or a cycler with a 'color' key.")
        if 'color' not in palette.keys:
            raise ValueError("Please set the palette key 'color'.")

        cc = palette()
        colors_list = [
            to_hex(next(cc)['color']) for x in range(len(categories))
        ]

    adata.uns[value_to_plot + '_colors'] = colors_list
 def setup(self):
     for label, value in self.data:
         if label is None and value is None:
             # Separator: (None, None)
             self.formlayout.addRow(QtWidgets.QLabel(" "), QtWidgets.QLabel(" "))
             self.widgets.append(None)
             continue
         elif label is None:
             # Comment
             self.formlayout.addRow(QtWidgets.QLabel(value))
             self.widgets.append(None)
             continue
         elif tuple_to_qfont(value) is not None:
             field = FontLayout(value, self)
         elif (label.lower() not in BLACKLIST
               and mcolors.is_color_like(value)):
             field = ColorLayout(to_qcolor(value), self)
         elif isinstance(value, six.string_types):
             field = QtWidgets.QLineEdit(value, self)
         elif isinstance(value, (list, tuple)):
             if isinstance(value, tuple):
                 value = list(value)
             selindex = value.pop(0)
             field = QtWidgets.QComboBox(self)
             if isinstance(value[0], (list, tuple)):
                 keys = [key for key, _val in value]
                 value = [val for _key, val in value]
             else:
                 keys = value
             field.addItems(value)
             if selindex in value:
                 selindex = value.index(selindex)
             elif selindex in keys:
                 selindex = keys.index(selindex)
             elif not isinstance(selindex, int):
                 warnings.warn(
                     "index '%s' is invalid (label: %s, value: %s)" %
                     (selindex, label, value))
                 selindex = 0
             field.setCurrentIndex(selindex)
         elif isinstance(value, bool):
             field = QtWidgets.QCheckBox(self)
             if value:
                 field.setCheckState(QtCore.Qt.Checked)
             else:
                 field.setCheckState(QtCore.Qt.Unchecked)
         elif isinstance(value, float):
             field = QtWidgets.QLineEdit(repr(value), self)
             field.setCursorPosition(0)
             field.setValidator(QtGui.QDoubleValidator(field))
             field.validator().setLocale(QtCore.QLocale("C"))
             dialog = self.get_dialog()
             dialog.register_float_field(field)
             field.textChanged.connect(lambda text: dialog.update_buttons())
         elif isinstance(value, int):
             field = QtWidgets.QSpinBox(self)
             field.setRange(-1e9, 1e9)
             field.setValue(value)
         elif isinstance(value, datetime.datetime):
             field = QtWidgets.QDateTimeEdit(self)
             field.setDateTime(value)
         elif isinstance(value, datetime.date):
             field = QtWidgets.QDateEdit(self)
             field.setDate(value)
         else:
             field = QtWidgets.QLineEdit(repr(value), self)
         self.formlayout.addRow(label, field)
         self.widgets.append(field)
예제 #35
0
def _get_color_values(adata,
                      value_to_plot,
                      groups=None,
                      palette=None,
                      use_raw=False):
    """
    Returns the value or color associated to each data point.
    For categorical data, the return value is list of colors taken
    from the category palette or from the given `palette` value.

    For non-categorical data, the values are returned
    """

    ###
    # when plotting, the color of the dots is determined for each plot
    # the data is either categorical or continuous and the data could be in
    # 'obs' or in 'var'
    categorical = False
    if value_to_plot is None:
        color_vector = 'lightgray'
    # check if value to plot is in obs
    elif value_to_plot in adata.obs.columns:
        if is_categorical_dtype(adata.obs[value_to_plot]):
            categorical = True

            if palette:
                # use category colors base on given palette
                _set_colors_for_categorical_obs(adata, value_to_plot, palette)
            else:
                if value_to_plot + '_colors' not in adata.uns or \
                    len(adata.uns[value_to_plot + '_colors']) < len(adata.obs[value_to_plot].cat.categories):
                    #  set a default palette in case that no colors or few colors are found
                    _set_default_colors_for_categorical_obs(
                        adata, value_to_plot)
                else:
                    # check that the colors in 'uns' are valid
                    _palette = []
                    for color in adata.uns[value_to_plot + '_colors']:
                        if not is_color_like(color):
                            # check if the color is a valid R color and translate it
                            # to a valid hex color value
                            if color in utils.additional_colors:
                                color = utils.additional_colors[color]
                            else:
                                logg.warn(
                                    "The following color value found in adata.uns['{}'] "
                                    " is not valid: '{}'. Default colors are used."
                                    .format(value_to_plot + '_colors', color))
                                _set_default_colors_for_categorical_obs(
                                    adata, value_to_plot)
                                _palette = None
                                break
                        _palette.append(color)
                    if _palette is not None:
                        adata.uns[value_to_plot + '_colors'] = _palette
            # for categorical data, colors should be
            # stored in adata.uns[value_to_plot + '_colors']
            # Obtain color vector by converting every category
            # into its respective color

            color_vector = [
                adata.uns[value_to_plot + '_colors'][x]
                for x in adata.obs[value_to_plot].cat.codes
            ]
            if groups is not None:
                if isinstance(groups, str):
                    groups = [groups]
                color_vector = np.array(color_vector, dtype='<U15')
                # set color to 'light gray' for all values
                # that are not in the groups
                color_vector[~adata.obs[value_to_plot].isin(groups
                                                            )] = "lightgray"
        else:
            color_vector = adata.obs[value_to_plot]

    # check if value to plot is in var
    elif use_raw is False and value_to_plot in adata.var_names:
        color_vector = adata[:, value_to_plot].X

    elif use_raw is True and value_to_plot in adata.raw.var_names:
        color_vector = adata.raw[:, value_to_plot].X
    else:
        raise ValueError(
            "The passed `color` {} is not a valid observation annotation "
            "or variable name. Valid observation annotation keys are: {}".
            format(value_to_plot, adata.obs.columns))

    return color_vector, categorical
예제 #36
0
def scatter_base(
    Y,
    colors='blue',
    sort_order=True,
    alpha=None,
    highlights=[],
    right_margin=None,
    left_margin=None,
    projection='2d',
    title=None,
    component_name='DC',
    component_indexnames=[1, 2, 3],
    axis_labels=None,
    colorbars=[False],
    sizes=[1],
    color_map='viridis',
    show_ticks=True,
    ax=None,
) -> Union[Axes, List[Axes]]:
    """Plot scatter plot of data.

    Parameters
    ----------
    Y : np.ndarray
        Data array.
    projection : {'2d', '3d'}

    Returns
    -------
    Depending on whether supplying a single array or a list of arrays,
    return a single axis or a list of axes.
    """
    if isinstance(highlights, dict):
        highlights_indices = sorted(highlights)
        highlights_labels = [highlights[i] for i in highlights_indices]
    else:
        highlights_indices = highlights
        highlights_labels = []
    # if we have a single array, transform it into a list with a single array
    if type(colors) == str: colors = [colors]
    if len(sizes) != len(colors) and len(sizes) == 1:
        sizes = [sizes[0] for i in range(len(colors))]
    axs, panel_pos, draw_region_width, figure_width = setup_axes(
        ax=ax,
        panels=colors,
        colorbars=colorbars,
        projection=projection,
        right_margin=right_margin,
        left_margin=left_margin,
        show_ticks=show_ticks)
    for icolor, color in enumerate(colors):
        ax = axs[icolor]
        left = panel_pos[2][2 * icolor]
        bottom = panel_pos[0][0]
        width = draw_region_width / figure_width
        height = panel_pos[1][0] - bottom
        Y_sort = Y
        if not is_color_like(color) and sort_order:
            sort = np.argsort(color)
            color = color[sort]
            Y_sort = Y[sort]
        if projection == '2d': data = Y_sort[:, 0], Y_sort[:, 1]
        elif projection == '3d':
            data = Y_sort[:, 0], Y_sort[:, 1], Y_sort[:, 2]
        if not isinstance(color, str) or color != 'white':
            sct = ax.scatter(
                *data,
                marker='.',
                c=color,
                alpha=alpha,
                edgecolors='none',  # 'face',
                s=sizes[icolor],
                cmap=color_map,
                rasterized=settings._vector_friendly)
        if colorbars[icolor]:
            width = 0.006 * draw_region_width / len(colors)
            left = panel_pos[2][2 * icolor + 1] + (1.2 if projection == '3d'
                                                   else 0.2) * width
            rectangle = [left, bottom, width, height]
            fig = pl.gcf()
            ax_cb = fig.add_axes(rectangle)
            cb = pl.colorbar(sct,
                             format=ticker.FuncFormatter(ticks_formatter),
                             cax=ax_cb)
        # set the title
        if title is not None: ax.set_title(title[icolor])
        # output highlighted data points
        for iihighlight, ihighlight in enumerate(highlights_indices):
            ihighlight = ihighlight if isinstance(ihighlight,
                                                  int) else int(ihighlight)
            data = [Y[ihighlight, 0]], [Y[ihighlight, 1]]
            if '3d' in projection:
                data = [Y[ihighlight, 0]], [Y[ihighlight,
                                              1]], [Y[ihighlight, 2]]
            ax.scatter(*data,
                       c='black',
                       facecolors='black',
                       edgecolors='black',
                       marker='x',
                       s=10,
                       zorder=20)
            highlight_text = (highlights_labels[iihighlight] if
                              len(highlights_labels) > 0 else str(ihighlight))
            # the following is a Python 2 compatibility hack
            ax.text(*([d[0] for d in data] + [highlight_text]),
                    zorder=20,
                    fontsize=10,
                    color='black')
        if not show_ticks:
            ax.set_xticks([])
            ax.set_yticks([])
            if '3d' in projection: ax.set_zticks([])
    # set default axis_labels
    if axis_labels is None:
        axis_labels = [[
            component_name + str(i) for i in idcs
        ] for idcs in [component_indexnames for iax in range(len(axs))]]
    else:
        axis_labels = [[axis_labels[0], axis_labels[1]]
                       for i in range(len(axs))]
    for iax, ax in enumerate(axs):
        ax.set_xlabel(axis_labels[iax][0])
        ax.set_ylabel(axis_labels[iax][1])
        if '3d' in projection:
            # shift the label closer to the axis
            ax.set_zlabel(axis_labels[iax][2], labelpad=-7)
    for ax in axs:
        # scale limits to match data
        ax.autoscale_view()
    return axs
예제 #37
0
    def plot_profile(self):

        if not self.color_list:
            cmap_plot = plt.get_cmap('jet')
            if self.numlines > 1:
                # kmeans, so we need to color by cluster
                self.color_list = cmap_plot(
                    np.arange(self.numlines, dtype=float) / self.numlines)
            else:
                self.color_list = cmap_plot(
                    np.arange(self.numplots, dtype=float) / self.numplots)
        if (self.numlines > 1 and len(self.color_list) < self.numlines) or\
           (self.numlines == 1 and len(self.color_list) < self.numplots):
            sys.exit("\nThe given list of colors is too small, "
                     "at least {} colors are needed\n".format(self.numlines))
        for color in self.color_list:
            if not pltcolors.is_color_like(color):
                sys.exit("\nThe color name {} is not valid. Check "
                         "the name or try with a html hex string "
                         "for example #eeff22".format(color))

        first = True
        ax_list = []
        for plot in range(self.numplots):
            col = plot % self.plots_per_row
            row = int(plot / self.plots_per_row)
            if row == 0 and col == 0:
                ax = self.fig.add_subplot(self.grids[row, col])
            else:
                ax = self.fig.add_subplot(self.grids[row, col],
                                          sharey=ax_list[0])

            if self.per_group:
                title = self.hm.matrix.group_labels[plot]
                if row != 0:
                    plt.setp(ax.get_yticklabels(), visible=False)
            else:
                title = self.hm.matrix.sample_labels[plot]
                if col != 0:
                    plt.setp(ax.get_yticklabels(), visible=False)

            ax.set_title(title)
            for data_idx in range(self.numlines):
                if self.per_group:
                    _row, _col = plot, data_idx
                else:
                    _row, _col = data_idx, plot

                sub_matrix = self.hm.matrix.get_matrix(_row, _col)

                if self.per_group:
                    label = sub_matrix['sample']
                else:
                    label = sub_matrix['group']

                if self.numlines > 1:
                    coloridx = data_idx
                else:
                    coloridx = plot
                plot_single(ax,
                            sub_matrix['matrix'],
                            self.averagetype,
                            self.color_list[coloridx],
                            label,
                            plot_type=self.plot_type)

            # remove the numbers of the y axis for all plots
            plt.setp(ax.get_yticklabels(), visible=False)

            if col == 0:
                # add the y axis label for the first plot
                # on each row and make the numbers and ticks visible
                plt.setp(ax.get_yticklabels(), visible=True)
                ax.axes.set_ylabel(self.y_axis_label)
                """
                # reduce the number of yticks by half
                num_ticks = len(ax.get_yticks())
                yticks = [ax.get_yticks()[i] for i in range(1, num_ticks, 2)]
                ax.set_yticks(yticks)
                """

            ax.axes.set_xticks(self.xticks)
            ax.axes.set_xticklabels(self.xtickslabel)
            # align the first and last label
            # such that they don't fall off
            # the heatmap sides
            ticks = ax.xaxis.get_major_ticks()
            ticks[0].label1.set_horizontalalignment('left')
            ticks[-1].label1.set_horizontalalignment('right')

            if first and self.plot_type not in ['heatmap', 'overlapped_lines']:
                ax.legend(loc=self.legend_location.replace('-', ' '),
                          ncol=1,
                          prop=self.font_p,
                          frameon=False,
                          markerscale=0.5)
                first = False
            """
            ax.legend(bbox_to_anchor=(-0.05, -1.13, 1., 1),
                      loc='upper center',
                      ncol=1, mode="expand", prop=font_p,
                      frameon=False, markerscale=0.5)
            """

            lims = ax.get_ylim()
            if self.y_min is not None:
                lims = (self.y_min, lims[1])
            if self.y_max is not None:
                lims = (lims[0], self.y_max)
            if lims[0] >= lims[1]:
                lims = (lims[0], lims[0] + 1)
            ax.set_ylim(lims)

            ax_list.append(ax)

        plt.subplots_adjust(wspace=0.05, hspace=0.3)
        plt.tight_layout()
        plt.savefig(self.out_file_name, dpi=200, format=self.image_format)
        plt.close()
예제 #38
0
파일: paga.py 프로젝트: taoliu/scanpy
def _paga_graph(
    adata,
    ax,
    solid_edges=None,
    dashed_edges=None,
    adjacency_solid=None,
    adjacency_dashed=None,
    transitions=None,
    threshold=None,
    root=0,
    colors=None,
    labels=None,
    fontsize=None,
    fontweight=None,
    fontoutline=None,
    text_kwds: Mapping[str, Any] = MappingProxyType({}),
    node_size_scale=1.,
    node_size_power=0.5,
    edge_width_scale=1.,
    normalize_to_color='reference',
    title=None,
    pos=None,
    cmap=None,
    frameon=True,
    min_edge_width=None,
    max_edge_width=None,
    export_to_gexf=False,
    colorbar=None,
    use_raw=True,
    cb_kwds: Mapping[str, Any] = MappingProxyType({}),
    single_component=False,
    arrowsize=30,
):
    import networkx as nx

    node_labels = labels  # rename for clarity
    if (node_labels is not None and isinstance(node_labels, str)
            and node_labels != adata.uns['paga']['groups']):
        raise ValueError(
            'Provide a list of group labels for the PAGA groups {}, not {}.'.
            format(adata.uns['paga']['groups'], node_labels))
    groups_key = adata.uns['paga']['groups']
    if node_labels is None:
        node_labels = adata.obs[groups_key].cat.categories

    if (colors is None or colors == groups_key) and groups_key is not None:
        if (groups_key + '_colors' not in adata.uns
                or len(adata.obs[groups_key].cat.categories) != len(
                    adata.uns[groups_key + '_colors'])):
            _utils.add_colors_for_categorical_sample_annotation(
                adata, groups_key)
        colors = adata.uns[groups_key + '_colors']
        for iname, name in enumerate(adata.obs[groups_key].cat.categories):
            if name in settings.categories_to_ignore: colors[iname] = 'grey'

    nx_g_solid = nx.Graph(adjacency_solid)
    if dashed_edges is not None:
        nx_g_dashed = nx.Graph(adjacency_dashed)

    # convert pos to array and dict
    if not isinstance(pos, (Path, str)):
        pos_array = pos
    else:
        pos = Path(pos)
        if pos.suffix != '.gdf':
            raise ValueError(
                'Currently only supporting reading positions from .gdf files. '
                'Consider generating them using, for instance, Gephi.')
        s = ''  # read the node definition from the file
        with pos.open() as f:
            f.readline()
            for line in f:
                if line.startswith('edgedef>'):
                    break
                s += line
        from io import StringIO
        df = pd.read_csv(StringIO(s), header=-1)
        pos_array = df[[4, 5]].values

    # convert to dictionary
    pos = {n: [p[0], p[1]] for n, p in enumerate(pos_array)}

    # uniform color
    if isinstance(colors, str) and is_color_like(colors):
        colors = [colors for c in range(len(node_labels))]

    # color degree of the graph
    if isinstance(colors, str) and colors.startswith('degree'):
        # see also tools.paga.paga_degrees
        if colors == 'degree_dashed':
            colors = [d for _, d in nx_g_dashed.degree(weight='weight')]
        elif colors == 'degree_solid':
            colors = [d for _, d in nx_g_solid.degree(weight='weight')]
        else:
            raise ValueError(
                '`degree` either "degree_dashed" or "degree_solid".')
        colors = (np.array(colors) - np.min(colors)) / (np.max(colors) -
                                                        np.min(colors))

    # plot gene expression
    var_names = adata.var_names if adata.raw is None else adata.raw.var_names
    if isinstance(colors, str) and colors in var_names:
        x_color = []
        cats = adata.obs[groups_key].cat.categories
        for icat, cat in enumerate(cats):
            subset = (cat == adata.obs[groups_key]).values
            if adata.raw is not None and use_raw:
                adata_gene = adata.raw[:, colors]
            else:
                adata_gene = adata[:, colors]
            x_color.append(np.mean(adata_gene.X[subset]))
        colors = x_color

    # plot continuous annotation
    if (isinstance(colors, str) and colors in adata.obs
            and not is_categorical_dtype(adata.obs[colors])):
        x_color = []
        cats = adata.obs[groups_key].cat.categories
        for icat, cat in enumerate(cats):
            subset = (cat == adata.obs[groups_key]).values
            x_color.append(adata.obs.loc[subset, colors].mean())
        colors = x_color

    # plot categorical annotation
    if (isinstance(colors, str) and colors in adata.obs
            and is_categorical_dtype(adata.obs[colors])):
        asso_names, asso_matrix = _sc_utils.compute_association_matrix_of_groups(
            adata,
            prediction=groups_key,
            reference=colors,
            normalization='reference' if normalize_to_color else 'prediction',
        )
        _utils.add_colors_for_categorical_sample_annotation(adata, colors)
        asso_colors = _sc_utils.get_associated_colors_of_groups(
            adata.uns[colors + '_colors'], asso_matrix)
        colors = asso_colors

    if len(colors) < len(node_labels):
        print(node_labels, colors)
        raise ValueError(
            '`color` list need to be at least as long as `groups`/`node_labels` list.'
        )

    # count number of connected components
    n_components, labels = scipy.sparse.csgraph.connected_components(
        adjacency_solid)
    if n_components > 1 and not single_component:
        logg.debug(
            'Graph has more than a single connected component. '
            'To restrict to this component, pass `single_component=True`.')
    if n_components > 1 and single_component:
        component_sizes = np.bincount(labels)
        largest_component = np.where(
            component_sizes == component_sizes.max())[0][0]
        adjacency_solid = adjacency_solid.tocsr()[labels ==
                                                  largest_component, :]
        adjacency_solid = adjacency_solid.tocsc()[:,
                                                  labels == largest_component]
        colors = np.array(colors)[labels == largest_component]
        node_labels = np.array(node_labels)[labels == largest_component]
        cats_dropped = adata.obs[groups_key].cat.categories[
            labels != largest_component].tolist()
        logg.info(
            'Restricting graph to largest connected component by dropping categories\n'
            f'{cats_dropped}')
        nx_g_solid = nx.Graph(adjacency_solid)
        if dashed_edges is not None:
            raise ValueError(
                '`single_component` only if `dashed_edges` is `None`.')

    # edge widths
    base_edge_width = edge_width_scale * 5 * rcParams['lines.linewidth']

    # draw dashed edges
    if dashed_edges is not None:
        widths = [x[-1]['weight'] for x in nx_g_dashed.edges(data=True)]
        widths = base_edge_width * np.array(widths)
        if max_edge_width is not None:
            widths = np.clip(widths, None, max_edge_width)
        nx.draw_networkx_edges(nx_g_dashed,
                               pos,
                               ax=ax,
                               width=widths,
                               edge_color='grey',
                               style='dashed',
                               alpha=0.5)

    # draw solid edges
    if transitions is None:
        widths = [x[-1]['weight'] for x in nx_g_solid.edges(data=True)]
        widths = base_edge_width * np.array(widths)
        if min_edge_width is not None or max_edge_width is not None:
            widths = np.clip(widths, min_edge_width, max_edge_width)
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            nx.draw_networkx_edges(nx_g_solid,
                                   pos,
                                   ax=ax,
                                   width=widths,
                                   edge_color='black')
    # draw directed edges
    else:
        adjacency_transitions = adata.uns['paga'][transitions].copy()
        if threshold is None: threshold = 0.01
        adjacency_transitions.data[adjacency_transitions.data < threshold] = 0
        adjacency_transitions.eliminate_zeros()
        g_dir = nx.DiGraph(adjacency_transitions.T)
        widths = [x[-1]['weight'] for x in g_dir.edges(data=True)]
        widths = base_edge_width * np.array(widths)
        if min_edge_width is not None or max_edge_width is not None:
            widths = np.clip(widths, min_edge_width, max_edge_width)
        nx.draw_networkx_edges(g_dir,
                               pos,
                               ax=ax,
                               width=widths,
                               edge_color='black',
                               arrowsize=arrowsize)

    if export_to_gexf:
        if isinstance(colors[0], tuple):
            from matplotlib.colors import rgb2hex
            colors = [rgb2hex(c) for c in colors]
        for count, n in enumerate(nx_g_solid.nodes()):
            nx_g_solid.node[count]['label'] = str(node_labels[count])
            nx_g_solid.node[count]['color'] = str(colors[count])
            nx_g_solid.node[count]['viz'] = dict(position=dict(
                x=1000 * pos[count][0],
                y=1000 * pos[count][1],
                z=0,
            ))
        filename = settings.writedir / 'paga_graph.gexf'
        logg.warning(f'exporting to {filename}')
        settings.writedir.mkdir(parents=True, exist_ok=True)
        nx.write_gexf(nx_g_solid, settings.writedir / 'paga_graph.gexf')

    ax.set_frame_on(frameon)
    ax.set_xticks([])
    ax.set_yticks([])

    # groups sizes
    if groups_key is not None and groups_key + '_sizes' in adata.uns:
        groups_sizes = adata.uns[groups_key + '_sizes']
    else:
        groups_sizes = np.ones(len(node_labels))
    base_scale_scatter = 2000
    base_pie_size = (base_scale_scatter /
                     (np.sqrt(adjacency_solid.shape[0]) + 10) *
                     node_size_scale)
    median_group_size = np.median(groups_sizes)
    groups_sizes = base_pie_size * np.power(groups_sizes / median_group_size,
                                            node_size_power)

    if fontsize is None:
        fontsize = rcParams['legend.fontsize']
    if fontoutline is not None:
        text_kwds = dict(text_kwds)
        text_kwds['path_effects'] = [
            patheffects.withStroke(linewidth=fontoutline, foreground='w')
        ]
    # usual scatter plot
    if not isinstance(colors[0], cabc.Mapping):
        n_groups = len(pos_array)
        sct = ax.scatter(pos_array[:, 0],
                         pos_array[:, 1],
                         c=colors[:n_groups],
                         edgecolors='face',
                         s=groups_sizes,
                         cmap=cmap)
        for count, group in enumerate(node_labels):
            ax.text(pos_array[count, 0],
                    pos_array[count, 1],
                    group,
                    verticalalignment='center',
                    horizontalalignment='center',
                    size=fontsize,
                    fontweight=fontweight,
                    **text_kwds)
    # else pie chart plot
    else:
        # start with this dummy plot... otherwise strange behavior
        sct = ax.scatter(pos_array[:, 0],
                         pos_array[:, 1],
                         c='white',
                         edgecolors='face',
                         s=groups_sizes,
                         cmap=cmap)
        trans = ax.transData.transform
        bbox = ax.get_position().get_points()
        ax_x_min = bbox[0, 0]
        ax_x_max = bbox[1, 0]
        ax_y_min = bbox[0, 1]
        ax_y_max = bbox[1, 1]
        ax_len_x = ax_x_max - ax_x_min
        ax_len_y = ax_y_max - ax_y_min
        trans2 = ax.transAxes.inverted().transform
        pie_axs = []
        for count, n in enumerate(nx_g_solid.nodes()):
            pie_size = groups_sizes[count] / base_scale_scatter
            x1, y1 = trans(pos[n])  # data coordinates
            xa, ya = trans2((x1, y1))  # axis coordinates
            xa = ax_x_min + (xa - pie_size / 2) * ax_len_x
            ya = ax_y_min + (ya - pie_size / 2) * ax_len_y
            # clip, the fruchterman layout sometimes places below figure
            if ya < 0: ya = 0
            if xa < 0: xa = 0
            pie_axs.append(
                pl.axes([xa, ya, pie_size * ax_len_x, pie_size * ax_len_y],
                        frameon=False))
            pie_axs[count].set_xticks([])
            pie_axs[count].set_yticks([])
            if not isinstance(colors[count], cabc.Mapping):
                raise ValueError(
                    f'{colors[count]} is neither a dict of valid '
                    'matplotlib colors nor a valid matplotlib color.')
            color_single = colors[count].keys()
            fracs = [colors[count][c] for c in color_single]
            if sum(fracs) < 1:
                color_single = list(color_single)
                color_single.append('grey')
                fracs.append(1 - sum(fracs))
            pie_axs[count].pie(fracs, colors=color_single)
        if node_labels is not None:
            for ia, a in enumerate(pie_axs):
                a.text(0.5,
                       0.5,
                       node_labels[ia],
                       verticalalignment='center',
                       horizontalalignment='center',
                       transform=a.transAxes,
                       size=fontsize,
                       fontweight=fontweight,
                       **text_kwds)
    return sct
예제 #39
0
    def _make_rows_of_violinplots(self, ax, _matrix, colormap_array, _color_df,
                                  x_spacer_size, y_spacer_size):
        import seaborn as sns  # Slow import, only import if called

        row_palette = self.kwds.get('color', self.row_palette)
        if 'color' in self.kwds:
            del self.kwds['color']
        if row_palette is not None:
            if is_color_like(row_palette):
                row_colors = [row_palette] * _color_df.shape[0]
            else:
                row_colors = sns.color_palette(row_palette,
                                               n_colors=_color_df.shape[0])
            # when row_palette is used, there is no need for a legend
            self.legends_width = 0.0
        else:
            row_colors = [None] * _color_df.shape[0]

        # All columns should have a unique name, yet, frequently
        # feature names are repeated in self.var_names,  otherwise the
        # violin plot will not distinguish those features
        _matrix.columns = [
            f"{x}_{idx}" for idx, x in enumerate(_matrix.columns)
        ]

        # transform the  dataframe into a dataframe having three columns:
        # the categories name (from groupby),
        # the feature name
        # the expression value
        # This format is convenient to aggregate per feature or per category
        # while making the violin plots.

        df = (pd.DataFrame(_matrix.stack(dropna=False)).reset_index().rename(
            columns={
                'level_1': 'features',
                _matrix.index.name: 'categories',
                0: 'values',
            }))
        df['features'] = (
            df['features'].astype('category').cat.reorder_categories(
                _matrix.columns))
        df['categories'] = (
            df['categories'].astype('category').cat.reorder_categories(
                _matrix.index.categories))

        # the ax need to be subdivided
        # define a layout of nrows = len(categories) rows
        # each row is one violin plot.
        num_rows, num_cols = _color_df.shape
        height_ratios = [y_spacer_size] + [1] * num_rows + [y_spacer_size]
        width_ratios = [x_spacer_size] + [1] * num_cols + [x_spacer_size]

        fig, gs = make_grid_spec(
            ax,
            nrows=num_rows + 2,
            ncols=num_cols + 2,
            hspace=0.2 if self.plot_yticklabels else 0,
            wspace=0,
            height_ratios=height_ratios,
            width_ratios=width_ratios,
        )
        axs_list = []
        for idx, row_label in enumerate(_color_df.index):

            row_ax = fig.add_subplot(gs[idx + 1, 1:-1])
            axs_list.append(row_ax)

            if row_colors[idx] is None:
                palette_colors = colormap_array[idx, :]
            else:
                palette_colors = None

            if not self.are_axes_swapped:
                x = 'features'
                _df = df[df.categories == row_label]
            else:
                x = 'categories'
                # because of the renamed matrix columns here
                # we need to use this instead of the 'row_label'
                # (in _color_df the values are not renamed as those
                # values will be used to label the ticks)
                _df = df[df.features == _matrix.columns[idx]]

            row_ax = sns.violinplot(
                x=x,
                y='values',
                data=_df,
                orient='vertical',
                ax=row_ax,
                palette=palette_colors,
                color=row_colors[idx],
                **self.kwds,
            )

            if self.stripplot:
                row_ax = sns.stripplot(
                    x=x,
                    y='values',
                    data=_df,
                    jitter=self.jitter,
                    color='black',
                    size=self.jitter_size,
                    ax=row_ax,
                )

            self._setup_violin_axes_ticks(row_ax, num_cols)
예제 #40
0
def show_Q(ar,
           scalebar=True,
           grid=False,
           polargrid=False,
           Q_pixel_size=None,
           Q_pixel_units=None,
           coordinates=None,
           rx=None,
           ry=None,
           qx0=None,
           qy0=None,
           e=None,
           theta=None,
           scalebarloc=0,
           scalebarsize=None,
           scalebarwidth=None,
           scalebartext=None,
           scalebartextloc='above',
           scalebartextsize=12,
           gridspacing=None,
           gridcolor='w',
           majorgridlines=True,
           majorgridlw=1,
           majorgridls=':',
           minorgridlines=True,
           minorgridlw=0.5,
           minorgridls=':',
           gridlabels=False,
           gridlabelsize=12,
           gridlabelcolor='k',
           alpha=0.35,
           **kwargs):
    """
    Shows a diffraction space image with options for several overlays to define the scale,
    including a scalebar, a cartesian grid, or a polar / polar-elliptical grid.

    Regardless of which overlay is requested, the function must recieve either values
    for Q_pixel_size and Q_pixel_units, or a Coordinates instance containing these values.
    If both are passed, the manually passed values take precedence.
    If a cartesian grid is requested, (qx0,qy0) are required, either passed manually or
    passed as a Coordinates instance with the appropriate (rx,ry) value.
    If a polar grid is requested, (qx0,qy0,e,theta) are required, again either manually
    or via a Coordinates instance.

    Any arguments accepted by the show() function (e.g. image scaling, clipvalues, etc)
    may be passed to this function as kwargs.
    """
    # Check inputs
    assert (isinstance(ar, np.ndarray) and len(ar.shape) == 2)
    if coordinates is not None:
        assert isinstance(coordinates, Coordinates)
    try:
        Q_pixel_size = Q_pixel_size if Q_pixel_size is not None else \
                       coordinates.get_Q_pixel_size()
    except AttributeError:
        raise Exception(
            "Q_pixel_size must be specified, either in coordinates or manually"
        )
    try:
        Q_pixel_units = Q_pixel_units if Q_pixel_units is not None else \
                       coordinates.get_Q_pixel_units()
    except AttributeError:
        raise Exception(
            "Q_pixel_size must be specified, either in coordinates or manually"
        )
    if grid or polargrid:
        try:
            qx0 = qx0 if qx0 is not None else coordinates.get_qx0(rx, ry)
        except AttributeError:
            raise Exception(
                "qx0 must be specified, either in coordinates or manually")
        try:
            qy0 = qy0 if qy0 is not None else coordinates.get_qy0(rx, ry)
        except AttributeError:
            raise Exception(
                "qy0 must be specified, either in coordinates or manually")
        assert isinstance(
            qx0, Number
        ), "Error: qx0 must be a number. If a Coordinate system was passed, try passing a position (rx,ry)."
        assert isinstance(
            qy0, Number
        ), "Error: qy0 must be a number. If a Coordinate system was passed, try passing a position (rx,ry)."
    if polargrid:
        e = e if e is not None else coordinates.get_e(rx, ry)
        theta = theta if theta is not None else coordinates.get_theta(rx, ry)
        assert isinstance(
            e, Number
        ), "Error: e must be a number. If a Coordinate system was passed, try passing a position (rx,ry)."
        assert isinstance(
            theta, Number
        ), "Error: theta must be a number. If a Coordinate system was passed, try passing a position (rx,ry)."

    # Make the plot
    fig, ax = show(ar, returnfig=True, **kwargs)

    # Add a scalebar
    if scalebar:
        pass

    # Add a cartesian grid
    if grid:
        # parse arguments
        assert isinstance(majorgridlines, bool)
        majorgridlw = majorgridlw if majorgridlines else 0
        assert isinstance(majorgridlw, Number)
        assert isinstance(majorgridls, str)
        assert isinstance(minorgridlines, bool)
        minorgridlw = minorgridlw if minorgridlines else 0
        assert isinstance(minorgridlw, Number)
        assert isinstance(minorgridls, str)
        assert is_color_like(gridcolor)
        assert isinstance(gridlabels, bool)
        assert isinstance(gridlabelsize, Number)
        assert is_color_like(gridlabelcolor)
        if gridspacing is not None:
            assert isinstance(gridspacing, Number)

        Q_Nx, Q_Ny = ar.shape
        assert qx0 < Q_Nx and qy0 < Q_Ny

        # Get the major grid-square size
        if gridspacing is None:
            D = np.mean((Q_Nx * Q_pixel_size, Q_Ny * Q_pixel_size)) / 2.
            exp = int(log(D, 10))
            if np.sign(log(D, 10)) < 0:
                exp -= 1
            base = D / (10**exp)
            if base >= 1 and base < 1.25:
                _gridspacing = 0.4
            elif base >= 1.25 and base < 1.75:
                _gridspacing = 0.5
            elif base >= 1.75 and base < 2.5:
                _gridspacing = 0.75
            elif base >= 2.5 and base < 3.25:
                _gridspacing = 1
            elif base >= 3.25 and base < 4.75:
                _gridspacing = 1.5
            elif base >= 4.75 and base < 6:
                _gridspacing = 2
            elif base >= 6 and base < 8:
                _gridspacing = 2.5
            elif base >= 8 and base < 10:
                _gridspacing = 3
            else:
                raise Exception("how did this happen?? base={}".format(base))
            gridspacing = _gridspacing * 10**exp

        # Get the positions and label for the major gridlines
        xmin = (-qx0) * Q_pixel_size
        xmax = (Q_Nx - 1 - qx0) * Q_pixel_size
        ymin = (-qy0) * Q_pixel_size
        ymax = (Q_Ny - 1 - qy0) * Q_pixel_size
        xticksmajor = np.concatenate(
            (-1 * np.arange(0, np.abs(xmin), gridspacing)[1:][::-1],
             np.arange(0, xmax, gridspacing)))
        yticksmajor = np.concatenate(
            (-1 * np.arange(0, np.abs(ymin), gridspacing)[1:][::-1],
             np.arange(0, ymax, gridspacing)))
        xticklabels = xticksmajor.copy()
        yticklabels = yticksmajor.copy()
        xticksmajor = (xticksmajor - xmin) / Q_pixel_size
        yticksmajor = (yticksmajor - ymin) / Q_pixel_size
        # Labels
        exp_spacing = int(np.round(log(gridspacing, 10), 6))
        if np.sign(log(gridspacing, 10)) < 0:
            exp_spacing -= 1
        base_spacing = gridspacing / (10**exp_spacing)
        xticklabels = xticklabels / (10**exp_spacing)
        yticklabels = yticklabels / (10**exp_spacing)
        if exp_spacing == 1:
            xticklabels *= 10
            yticklabels *= 10
        if _gridspacing in (0.4, 0.75, 1.5, 2.5) and exp_spacing != 1:
            xticklabels = ["{:.1f}".format(n) for n in xticklabels]
            yticklabels = ["{:.1f}".format(n) for n in yticklabels]
        else:
            xticklabels = ["{:.0f}".format(n) for n in xticklabels]
            yticklabels = ["{:.0f}".format(n) for n in yticklabels]

        # Add the grid
        ax.set_xticks(yticksmajor)
        ax.set_yticks(xticksmajor)
        ax.xaxis.set_ticks_position('bottom')
        if gridlabels:
            ax.set_xticklabels(yticklabels,
                               size=gridlabelsize,
                               color=gridlabelcolor)
            ax.set_yticklabels(xticklabels,
                               size=gridlabelsize,
                               color=gridlabelcolor)
            if exp_spacing in (0, 1):
                ax.set_xlabel(r"$q_y$ (" + Q_pixel_units + ")")
                ax.set_ylabel(r"$q_x$ (" + Q_pixel_units + ")")
            else:
                ax.set_xlabel(r"$q_y$ (" + Q_pixel_units + " e" +
                              str(exp_spacing) + ")")
                ax.set_ylabel(r"$q_x$ (" + Q_pixel_units + " e" +
                              str(exp_spacing) + ")")
        else:
            ax.set_xticklabels([])
            ax.set_yticklabels([])
        ax.grid(linestyle=majorgridls,
                linewidth=majorgridlw,
                color=gridcolor,
                alpha=alpha)

        # Add the grid
        if majorgridlines:
            add_cartesian_grid(ax,
                               d={
                                   'x0': qx0,
                                   'y0': qy0,
                                   'spacing': gridspacing,
                                   'majorlw': majorgridlw,
                                   'majorls': majorgridls,
                                   'minorlw': minorgridlw,
                                   'minorls': minorgridls,
                                   'color': gridcolor,
                                   'label': gridlabels,
                                   'labelsize': gridlabelsize,
                                   'labelcolor': gridlabelcolor,
                                   'alpha': alpha
                               })
        if minorgridlines:
            add_cartesian_grid(ax,
                               d={
                                   'x0': qx0,
                                   'y0': qy0,
                                   'spacing': gridspacing,
                                   'majorlw': majorgridlw,
                                   'majorls': majorgridls,
                                   'minorlw': minorgridlw,
                                   'minorls': minorgridls,
                                   'color': gridcolor,
                                   'label': gridlabels,
                                   'labelsize': gridlabelsize,
                                   'labelcolor': gridlabelcolor,
                                   'alpha': alpha
                               })

    # Add a polar-elliptical grid
    if polargrid:
        pass

    return
예제 #41
0
def iscolor(c):
    return mcolors.is_color_like(c)
예제 #42
0
def _valid_addplot_kwargs():

    valid_linestyles = ('-', 'solid', '--', 'dashed', '-.', 'dashdot', '.',
                        'dotted', None, ' ', '')
    #valid_types = ('line','scatter','bar','ohlc','candle')
    valid_types = ('line', 'scatter', 'bar')

    vkwargs = {
        'scatter': {
            'Default': False,
            'Validator': lambda value: isinstance(value, bool)
        },
        'type': {
            'Default': 'line',
            'Validator': lambda value: value in valid_types
        },
        'panel': {
            'Default': 0,
            'Validator': lambda value: _valid_panel_id(value)
        },
        'marker': {
            'Default': 'o',
            'Validator': lambda value: _bypass_kwarg_validation(value)
        },
        'markersize': {
            'Default': 18,
            'Validator': lambda value: isinstance(value, (int, float))
        },
        'color': {
            'Default':
            None,
            'Validator':
            lambda value: mcolors.is_color_like(value) or
            (isinstance(value, (list, tuple, np.ndarray)) and all(
                [mcolors.is_color_like(v) for v in value]))
        },
        'linestyle': {
            'Default': None,
            'Validator': lambda value: value in valid_linestyles
        },
        'width': {
            'Default':
            0.8,
            'Validator':
            lambda value: isinstance(value, (int, float)) or all(
                [isinstance(v, (int, float)) for v in value])
        },
        'bottom': {
            'Default':
            0,
            'Validator':
            lambda value: isinstance(value, (int, float)) or all(
                [isinstance(v, (int, float)) for v in value])
        },
        'alpha': {
            'Default':
            1,
            'Validator':
            lambda value: isinstance(value, (int, float)) or all(
                [isinstance(v, (int, float)) for v in value])
        },
        'secondary_y': {
            'Default': 'auto',
            'Validator':
            lambda value: isinstance(value, bool) or value == 'auto'
        },
        'ylabel': {
            'Default': None,
            'Validator': lambda value: isinstance(value, str)
        },
    }

    _validate_vkwargs_dict(vkwargs)

    return vkwargs
예제 #43
0
 def setup(self):
     for label, value in self.data:
         if DEBUG:
             print("value:", value)
         if label is None and value is None:
             # Separator: (None, None)
             self.formlayout.addRow(QtGui.QLabel(" "), QtGui.QLabel(" "))
             self.widgets.append(None)
             continue
         elif label is None:
             # Comment
             self.formlayout.addRow(QtGui.QLabel(value))
             self.widgets.append(None)
             continue
         elif tuple_to_qfont(value) is not None:
             field = FontLayout(value, self)
         elif is_color_like(value):
             field = ColorLayout(to_qcolor(value), self)
         elif isinstance(value, (str, unicode)):
             field = QtGui.QLineEdit(value, self)
         elif isinstance(value, (list, tuple)):
             if isinstance(value, tuple):
                 value = list(value)
             selindex = value.pop(0)
             field = QtGui.QComboBox(self)
             if isinstance(value[0], (list, tuple)):
                 keys = [ key for key, _val in value ]
                 value = [ val for _key, val in value ]
             else:
                 keys = value
             field.addItems(value)
             if selindex in value:
                 selindex = value.index(selindex)
             elif selindex in keys:
                 selindex = keys.index(selindex)
             elif not isinstance(selindex, int):
                 print("Warning: '%s' index is invalid (label: " \
                                 "%s, value: %s)" % (selindex, label, value), file=STDERR)
                 selindex = 0
             field.setCurrentIndex(selindex)
         elif isinstance(value, bool):
             field = QtGui.QCheckBox(self)
             if value:
                 field.setCheckState(QtCore.Qt.Checked)
             else :
                 field.setCheckState(QtCore.Qt.Unchecked)
         elif isinstance(value, float):
             field = QtGui.QLineEdit(repr(value), self)
             field.setValidator(QtGui.QDoubleValidator(field))
             dialog = self.get_dialog()
             dialog.register_float_field(field)
             self.connect(field, QtCore.SIGNAL('textChanged(QString)'),
                          lambda text: dialog.update_buttons())
         elif isinstance(value, int):
             field = QtGui.QSpinBox(self)
             field.setRange(-1e9, 1e9)
             field.setValue(value)
         elif isinstance(value, datetime.datetime):
             field = QtGui.QDateTimeEdit(self)
             field.setDateTime(value)
         elif isinstance(value, datetime.date):
             field = QtGui.QDateEdit(self)
             field.setDate(value)
         else:
             field = QtGui.QLineEdit(repr(value), self)
         self.formlayout.addRow(label, field)
         self.widgets.append(field)
예제 #44
0
파일: images.py 프로젝트: bobi5rova/cecog
def grey2rgb(image, color="#FFFFFF"):
    if is_color_like(color):
        color = hex2color(color)
    # be aware that color contains floats ranging from 0 to 1
    return np.dstack((image, image, image))*np.array(color)
예제 #45
0
    def plot_segmentlist(self, segmentlist, y=None, height=.8, label=None,
                         collection=True, rasterized=None, **kwargs):
        """Plot a `~gwpy.segments.SegmentList` onto these axes

        Parameters
        ----------
        segmentlist : `~gwpy.segments.SegmentList`
            list of segments to display

        y : `float`, optional
            y-axis value for new segments

        collection : `bool`, default: `True`
            add all patches as a
            `~matplotlib.collections.PatchCollection`, doesn't seem
            to work for hatched rectangles

        label : `str`, optional
            custom descriptive name to print as y-axis tick label

        **kwargs
            any other keyword arguments acceptable for
            `~matplotlib.patches.Rectangle`

        Returns
        -------
        collection : `~matplotlib.patches.PatchCollection`
            list of `~matplotlib.patches.Rectangle` patches
        """
        # get colour
        facecolor = kwargs.pop('facecolor', kwargs.pop('color', '#629fca'))
        if is_color_like(facecolor):
            kwargs.setdefault('edgecolor', tint(facecolor, factor=.5))

        # get y
        if y is None:
            y = self.get_next_y()

        # build patches
        patches = [SegmentRectangle(seg, y, height=height, facecolor=facecolor,
                                    **kwargs) for seg in segmentlist]

        if collection:  # map to PatchCollection
            coll = PatchCollection(patches, match_original=patches,
                                   zorder=kwargs.get('zorder', 1))
            coll.set_rasterized(rasterized)
            coll._ignore = collection == 'ignore'
            coll._ypos = y
            out = self.add_collection(coll)
            # reset label with tex-formatting now
            #   matplotlib default label is applied by add_collection
            #   so we can only replace the leading underscore after
            #   this point
            if label is None:
                label = coll.get_label()
            coll.set_label(to_string(label))
        else:
            out = []
            for patch in patches:
                patch.set_label(label)
                patch.set_rasterized(rasterized)
                label = ''
                out.append(self.add_patch(patch))
        self.autoscale(enable=None, axis='both', tight=False)
        return out
예제 #46
0
def _valid_addplot_kwargs():

    valid_linestyles = ('-', 'solid', '--', 'dashed', '-.', 'dashdot', '.',
                        'dotted', None, ' ', '')
    valid_types = ('line', 'scatter', 'bar', 'ohlc', 'candle')

    vkwargs = {
        'scatter': {
            'Default': False,
            'Validator': lambda value: isinstance(value, bool)
        },
        'type': {
            'Default': 'line',
            'Validator': lambda value: value in valid_types
        },
        'mav': {
            'Default': None,
            'Validator': _mav_validator
        },
        'panel': {
            'Default': 0,
            'Validator': lambda value: _valid_panel_id(value)
        },
        'marker': {
            'Default': 'o',
            'Validator': lambda value: _bypass_kwarg_validation(value)
        },
        'markersize': {
            'Default': 18,
            'Validator': lambda value: isinstance(value, (int, float))
        },
        'color': {
            'Default':
            None,
            'Validator':
            lambda value: mcolors.is_color_like(value) or
            (isinstance(value, (list, tuple, np.ndarray)) and all(
                [mcolors.is_color_like(v) for v in value]))
        },
        'linestyle': {
            'Default': None,
            'Validator': lambda value: value in valid_linestyles
        },
        'width': {
            'Default':
            None,  # width of `bar` or `line` 
            'Validator':
            lambda value: isinstance(value, (int, float)) or all(
                [isinstance(v, (int, float)) for v in value])
        },
        'bottom': {
            'Default':
            0,  # bottom for `type=bar` plots
            'Validator':
            lambda value: isinstance(value, (int, float)) or all(
                [isinstance(v, (int, float)) for v in value])
        },
        'alpha': {
            'Default':
            1,  # alpha of `bar`, `line`, or `scatter`
            'Validator':
            lambda value: isinstance(value, (int, float)) or all(
                [isinstance(v, (int, float)) for v in value])
        },
        'secondary_y': {
            'Default': 'auto',
            'Validator':
            lambda value: isinstance(value, bool) or value == 'auto'
        },
        'y_on_right': {
            'Default': None,
            'Validator': lambda value: isinstance(value, bool)
        },
        'ylabel': {
            'Default': None,
            'Validator': lambda value: isinstance(value, str)
        },
        'ylim': {
            'Default':
            None,
            'Validator':
            lambda value: isinstance(value, (list, tuple)) and len(value) == 2
            and all([isinstance(v, (int, float)) for v in value])
        },
        'title': {
            'Default': None,
            'Validator': lambda value: isinstance(value, str)
        },
        'ax': {
            'Default': None,
            'Validator': lambda value: isinstance(value, mpl_axes.Axes)
        },
        'yscale': {
            'Default': None,
            'Validator': lambda value: _yscale_validator(value)
        },
    }

    _validate_vkwargs_dict(vkwargs)

    return vkwargs
예제 #47
0
def add_bragg_index_labels(ax,d):
    """
    Adds labels for indexed bragg directions to a plot, using the parameters in dict d.

    The dictionary d has required and optional parameters as follows:
        braggdirections (req'd) (PointList) the Bragg directions. This PointList must have
                        the fields 'qx','qy','h', and 'k', and may optionally have 'l'
        voffset         (number) vertical offset for the labels
        hoffset         (number) horizontal offset for the labels
        color           (color)
        size            (number)
        points          (bool)
        pointsize       (number)
        pointcolor      (color)
    """
    # handle inputs
    assert isinstance(ax,Axes)
    # bragg directions
    assert('braggdirections' in d.keys())
    braggdirections = d['braggdirections']
    assert isinstance(braggdirections,PointList)
    for k in ('qx','qy','h','k'):
        assert k in braggdirections.data.dtype.fields
    include_l = True if 'l' in braggdirections.data.dtype.fields else False
    # offsets
    hoffset = d['hoffset'] if 'hoffset' in d.keys() else 0
    voffset = d['voffset'] if 'voffset' in d.keys() else 5
    # size, color
    size = d['size'] if 'size' in d.keys() else 20
    assert isinstance(size,Number)
    color = d['color'] if 'color' in d.keys() else 'w'
    assert is_color_like(color)
    # points
    points = d['points'] if 'points' in d.keys() else True
    pointsize = d['pointsize'] if 'pointsize' in d.keys() else 50
    pointcolor = d['pointcolor'] if 'pointcolor' in d.keys() else 'r'
    assert isinstance(points,bool)
    assert isinstance(pointsize,Number)
    assert is_color_like(pointcolor)

    # add the points
    if points:
        ax.scatter(braggdirections.data['qy'],braggdirections.data['qx'],
                   color=pointcolor,s=pointsize)

    # add index labels
    for i in range(braggdirections.length):
        x,y = braggdirections.data['qx'][i],braggdirections.data['qy'][i]
        x -= voffset
        y += hoffset
        h,k = braggdirections.data['h'][i],braggdirections.data['k'][i]
        h = str(h) if h>=0 else '$\overline{{{}}}$'.format(np.abs(h))
        k = str(k) if k>=0 else '$\overline{{{}}}$'.format(np.abs(k))
        s = h+','+k
        if include_l:
            l = braggdirections.data['l'][i]
            l = str(l) if l>=0 else '$\overline{{{}}}$'.format(np.abs(l))
            s += l
        ax.text(y,x,s,color=color,size=size,ha='center',va='bottom')

    return
예제 #48
0
 def setup(self):
     for label, value in self.data:
         if DEBUG:
             print("value:", value)
         if label is None and value is None:
             # Separator: (None, None)
             self.formlayout.addRow(QtWidgets.QLabel(" "), QtWidgets.QLabel(" "))
             self.widgets.append(None)
             continue
         elif label is None:
             # Comment
             self.formlayout.addRow(QtWidgets.QLabel(value))
             self.widgets.append(None)
             continue
         elif tuple_to_qfont(value) is not None:
             field = FontLayout(value, self)
         elif (label.lower() not in BLACKLIST
               and mcolors.is_color_like(value)):
             field = ColorLayout(to_qcolor(value), self)
         elif isinstance(value, six.string_types):
             field = QtWidgets.QLineEdit(value, self)
         elif isinstance(value, (list, tuple)):
             if isinstance(value, tuple):
                 value = list(value)
             selindex = value.pop(0)
             field = QtWidgets.QComboBox(self)
             if isinstance(value[0], (list, tuple)):
                 keys = [key for key, _val in value]
                 value = [val for _key, val in value]
             else:
                 keys = value
             field.addItems(value)
             if selindex in value:
                 selindex = value.index(selindex)
             elif selindex in keys:
                 selindex = keys.index(selindex)
             elif not isinstance(selindex, int):
                 warnings.warn(
                     "index '%s' is invalid (label: %s, value: %s)" %
                     (selindex, label, value))
                 selindex = 0
             field.setCurrentIndex(selindex)
         elif isinstance(value, bool):
             field = QtWidgets.QCheckBox(self)
             if value:
                 field.setCheckState(QtCore.Qt.Checked)
             else:
                 field.setCheckState(QtCore.Qt.Unchecked)
         elif isinstance(value, float):
             field = QtWidgets.QLineEdit(repr(value), self)
             field.setCursorPosition(0)
             field.setValidator(QtGui.QDoubleValidator(field))
             field.validator().setLocale(QtCore.QLocale("C"))
             dialog = self.get_dialog()
             dialog.register_float_field(field)
             field.textChanged.connect(lambda text: dialog.update_buttons())
         elif isinstance(value, int):
             field = QtWidgets.QSpinBox(self)
             field.setRange(-1e9, 1e9)
             field.setValue(value)
         elif isinstance(value, datetime.datetime):
             field = QtWidgets.QDateTimeEdit(self)
             field.setDateTime(value)
         elif isinstance(value, datetime.date):
             field = QtWidgets.QDateEdit(self)
             field.setDate(value)
         else:
             field = QtWidgets.QLineEdit(repr(value), self)
         self.formlayout.addRow(label, field)
         self.widgets.append(field)
예제 #49
0
def add_annuli(ax,d):
    """
    Adds one or more annuli to Axis ax using the parameters in dictionary d.
    """
    # Handle inputs
    assert isinstance(ax,Axes)
    # center
    assert('center' in d.keys())
    center = d['center']
    if isinstance(center,tuple):
        assert(len(center)==2)
        center = [center]
    assert(isinstance(center,list))
    N = len(center)
    assert(all([isinstance(x,tuple) for x in center]))
    assert(all([len(x)==2 for x in center]))
    # radii
    assert('Ri' in d.keys())
    assert('Ro' in d.keys())
    Ri,Ro = d['Ri'],d['Ro']
    if isinstance(Ri,Number):
        Ri = [Ri for i in range(N)]
    if isinstance(Ro,Number):
        Ro = [Ro for i in range(N)]
    assert(isinstance(Ri,list))
    assert(isinstance(Ro,list))
    assert(len(Ri)==N)
    assert(len(Ro)==N)
    assert(all([isinstance(i,Number) for i in Ri]))
    assert(all([isinstance(i,Number) for i in Ro]))
    # color
    color = d['color'] if 'color' in d.keys() else 'r'
    if isinstance(color,list):
        assert(len(color)==N)
        assert(all([is_color_like(c) for c in color]))
    else:
        assert is_color_like(color)
        color = [color for i in range(N)]
    # fill
    fill = d['fill'] if 'fill' in d.keys() else False
    if isinstance(fill,bool):
        fill = [fill for i in range(N)]
    else:
        assert(isinstance(fill,list))
        assert(len(fill)==N)
        assert(all([isinstance(f,bool) for f in fill]))
    # alpha
    alpha = d['alpha'] if 'alpha' in d.keys() else 1
    if isinstance(alpha,(float,int,np.float)):
        alpha = [alpha for i in range(N)]
    else:
        assert(isinstance(alpha,list))
        assert(len(alpha)==N)
        assert(all([isinstance(a,(float,int,np.float)) for a in alpha]))
    # linewidth
    linewidth = d['linewidth'] if 'linewidth' in d.keys() else 2
    if isinstance(linewidth,(float,int,np.float)):
        linewidth = [linewidth for i in range(N)]
    else:
        assert(isinstance(linewidth,list))
        assert(len(linewidth)==N)
        assert(all([isinstance(lw,(float,int,np.float)) for lw in linewidth]))
    # additional parameters
    kws = [k for k in d.keys() if k not in ('center','Ri','Ro','color','fill','alpha','linewidth')]
    kwargs = dict()
    for k in kws:
        kwargs[k] = d[k]

    # add the annuli
    for i in range(N):
        cent,ri,ro,col,f,a,lw = center[i],Ri[i],Ro[i],color[i],fill[i],alpha[i],linewidth[i]
        annulus = Wedge((cent[1],cent[0]),ro,0,360,width=ro-ri,color=col,fill=f,alpha=a,
                        linewidth=lw,**kwargs)
        ax.add_patch(annulus)

    return
예제 #50
0
def add_ellipses(ax,d):
    """
    Adds one or more ellipses to axis ax using the parameters in dictionary d.

    Parameters:
        center
        a
        b
        theta
        color
        fill
        alpha
        linewidth
        linestyle
    """
    # handle inputs
    assert isinstance(ax,Axes)
    # semimajor axis length
    assert('a' in d.keys())
    a = d['a']
    if isinstance(a,Number):
        a = [a]
    assert(isinstance(a,list))
    N = len(a)
    assert(all([isinstance(i,Number) for i in a]))
    # semiminor axis length
    assert('b' in d.keys())
    b = d['b']
    if isinstance(b,Number):
        b = [b]
    assert(isinstance(b,list))
    assert(len(b)==N)
    assert(all([isinstance(i,Number) for i in b]))
    # center
    assert('center' in d.keys())
    center = d['center']
    if isinstance(center,tuple):
        assert(len(center)==2)
        center = [center for i in range(N)]
    assert(isinstance(center,list))
    assert(len(center)==N)
    assert(all([isinstance(x,tuple) for x in center]))
    assert(all([len(x)==2 for x in center]))
    # theta
    assert('theta' in d.keys())
    theta = d['theta']
    if isinstance(theta,Number):
        theta = [theta for i in range(N)]
    assert(isinstance(theta,list))
    assert(len(theta)==N)
    assert(all([isinstance(i,Number) for i in theta]))
    # color
    color = d['color'] if 'color' in d.keys() else 'r'
    if isinstance(color,list):
        assert(len(color)==N)
        assert(all([is_color_like(c) for c in color]))
    else:
        assert is_color_like(color)
        color = [color for i in range(N)]
    # fill
    fill = d['fill'] if 'fill' in d.keys() else False
    if isinstance(fill,bool):
        fill = [fill for i in range(N)]
    else:
        assert(isinstance(fill,list))
        assert(len(fill)==N)
        assert(all([isinstance(f,bool) for f in fill]))
    # alpha
    alpha = d['alpha'] if 'alpha' in d.keys() else 1
    if isinstance(alpha,(float,int,np.float)):
        alpha = [alpha for i in range(N)]
    else:
        assert(isinstance(alpha,list))
        assert(len(alpha)==N)
        assert(all([isinstance(alp,(float,int,np.float)) for alp in alpha]))
    # linewidth
    linewidth = d['linewidth'] if 'linewidth' in d.keys() else 2
    if isinstance(linewidth,(float,int,np.float)):
        linewidth = [linewidth for i in range(N)]
    else:
        assert(isinstance(linewidth,list))
        assert(len(linewidth)==N)
        assert(all([isinstance(lw,(float,int,np.float)) for lw in linewidth]))
    # linestyle
    linestyle = d['linestyle'] if 'linestyle' in d.keys() else '-'
    if isinstance(linestyle,(str)):
        linestyle = [linestyle for i in range(N)]
    else:
        assert(isinstance(linestyle,list))
        assert(len(linestyle)==N)
        assert(all([isinstance(lw,(str)) for lw in linestyle]))
    # additional parameters
    kws = [k for k in d.keys() if k not in ('center','a','b','theta','color',
                                            'fill','alpha','linewidth','linestyle')]
    kwargs = dict()
    for k in kws:
        kwargs[k] = d[k]

    # add the ellipses
    for i in range(N):
        cent,_a,_b,_theta,col,f,_alpha,lw,ls = (center[i],a[i],b[i],theta[i],color[i],fill[i],
                                                alpha[i],linewidth[i],linestyle[i])
        ellipse = Ellipse((cent[1],cent[0]),2*_b,2*_a,-np.degrees(_theta),color=col,fill=f,
                        alpha=_alpha,linewidth=lw,linestyle=ls,**kwargs)
        ax.add_patch(ellipse)

    return
예제 #51
0
    def plot_profile(self):
        if self.y_min is None:
            self.y_min = [None]
        if self.y_max is None:
            self.y_max = [None]

        if not self.color_list:
            cmap_plot = plt.get_cmap('jet')
            if self.numlines > 1:
                # kmeans, so we need to color by cluster
                self.color_list = cmap_plot(np.arange(self.numlines, dtype=float) / float(self.numlines))
            else:
                self.color_list = cmap_plot(np.arange(self.numplots, dtype=float) / float(self.numplots))
        if (self.numlines > 1 and len(self.color_list) < self.numlines) or\
           (self.numlines == 1 and len(self.color_list) < self.numplots):
            sys.exit("\nThe given list of colors is too small, "
                     "at least {} colors are needed\n".format(self.numlines))
        for color in self.color_list:
            if not pltcolors.is_color_like(color):
                sys.exit("\nThe color name {} is not valid. Check "
                         "the name or try with a html hex string "
                         "for example #eeff22".format(color))

        if self.image_format == "plotly":
            return self.plotly_profile()

        first = True
        ax_list = []
        globalYmin = np.inf
        globalYmax = -np.inf
        for plot in range(self.numplots):
            localYMin = None
            localYMax = None
            col = plot % self.plots_per_row
            row = int(plot / float(self.plots_per_row))
            if (row == 0 and col == 0) or len(self.y_min) > 1 or len(self.y_max) > 1:
                ax = self.fig.add_subplot(self.grids[row, col])
            else:
                ax = self.fig.add_subplot(self.grids[row, col])

            if self.per_group:
                title = self.hm.matrix.group_labels[plot]
                if row != 0 and len(self.y_min) == 1 and len(self.y_max) == 1:
                    plt.setp(ax.get_yticklabels(), visible=False)
                tickIdx = plot % self.hm.matrix.get_num_samples()
            else:
                title = self.hm.matrix.sample_labels[plot]
                if col != 0 and len(self.y_min) == 1 and len(self.y_max) == 1:
                    plt.setp(ax.get_yticklabels(), visible=False)
                tickIdx = plot

            ax.set_title(title)
            for data_idx in range(self.numlines):
                if self.per_group:
                    _row, _col = plot, data_idx
                else:
                    _row, _col = data_idx, plot
                if localYMin is None or self.y_min[col % len(self.y_min)] < localYMin:
                    localYMin = self.y_min[col % len(self.y_min)]
                if localYMax is None or self.y_max[col % len(self.y_max)] > localYMax:
                    localYMax = self.y_max[col % len(self.y_max)]

                sub_matrix = self.hm.matrix.get_matrix(_row, _col)

                if self.per_group:
                    label = sub_matrix['sample']
                else:
                    label = sub_matrix['group']

                if self.numlines > 1:
                    coloridx = data_idx
                else:
                    coloridx = plot
                plot_single(ax, sub_matrix['matrix'],
                            self.averagetype,
                            self.color_list[coloridx],
                            label,
                            plot_type=self.plot_type)
            globalYmin = min(np.float64(globalYmin), ax.get_ylim()[0])
            globalYmax = max(globalYmax, ax.get_ylim()[1])

            # remove the numbers of the y axis for all plots
            plt.setp(ax.get_yticklabels(), visible=False)

            if col == 0 or len(self.y_min) > 1 or len(self.y_max) > 1:
                # add the y axis label for the first plot
                # on each row and make the numbers and ticks visible
                plt.setp(ax.get_yticklabels(), visible=True)
                ax.axes.set_ylabel(self.y_axis_label)

            totalWidth = sub_matrix['matrix'].shape[1]
            xticks, xtickslabel = self.getTicks(tickIdx)
            if np.ceil(max(xticks)) != float(totalWidth):
                tickscale = float(totalWidth) / max(xticks)
                xticks_use = [x * tickscale for x in xticks]
                ax.axes.set_xticks(xticks_use)
            else:
                ax.axes.set_xticks(xticks)
            ax.axes.set_xticklabels(xtickslabel, rotation=self.label_rotation)
            # align the first and last label
            # such that they don't fall off
            # the heatmap sides
            ticks = ax.xaxis.get_major_ticks()
            ticks[0].label1.set_horizontalalignment('left')
            ticks[-1].label1.set_horizontalalignment('right')

            if first and self.plot_type not in ['heatmap', 'overlapped_lines']:
                ax.legend(loc=self.legend_location.replace('-', ' '),
                          ncol=1, prop=self.font_p,
                          frameon=False, markerscale=0.5)
                if len(self.y_min) == 1 and len(self.y_max) == 1:
                    first = False
            ax_list.append(ax)

        # It turns out that set_ylim only takes np.float64s
        for sample_id, subplot in enumerate(ax_list):
            localYMin = self.y_min[sample_id % len(self.y_min)]
            localYMax = self.y_max[sample_id % len(self.y_max)]
            lims = [globalYmin, globalYmax]
            if localYMin is not None:
                if localYMax is not None:
                    lims = (np.float64(localYMin), np.float64(localYMax))
                else:
                    lims = (np.float64(localYMin), lims[1])
            elif localYMax is not None:
                lims = (lims[0], np.float64(localYMax))
            if lims[0] >= lims[1]:
                lims = (lims[0], lims[0] + 1)
            ax_list[sample_id].set_ylim(lims)

        plt.subplots_adjust(wspace=0.05, hspace=0.3)
        plt.tight_layout()
        plt.savefig(self.out_file_name, dpi=self.dpi, format=self.image_format)
        plt.close()