(self, parts: 'Parts')
Set the heatmap parts for display
Set the heatmap parts for display
Set the heatmap parts for display
def setHeatmaps(self, parts: 'Parts') -> None:
        """Set the heatmap parts for display"""
        self.clear()
        grid = self.__layout
        N, M = len(parts.rows), len(parts.columns)

        # Start row/column where the heatmap items are inserted
        # (after the titles/legends/dendrograms)
        Row0 = self.Row0
        Col0 = self.Col0
        # The column for the vertical dendrograms
        DendrogramColumn = self.DendrogramColumn
        # The row for the horizontal dendrograms
        DendrogramRow = self.DendrogramRow
        RightLabelColumn = Col0 + 2 * M + 1
        TopAnnotationRow = self.TopAnnotationRow
        TopLabelsRow = self.TopLabelsRow
        BottomLabelsRow = Row0 + N
        colormap = self.__colormap
        column_dendrograms: List[Optional[DendrogramWidget]] = [None] * M
        row_dendrograms: List[Optional[DendrogramWidget]] = [None] * N
        right_side_colors: List[Optional[GraphicsPixmapWidget]] = [None] * N
        top_side_colors: List[Optional[GraphicsPixmapWidget]] = [None] * M

        data = parts.data
        if parts.col_names is None:
            col_names = np.full(data.shape[1], "", dtype=object)
        else:
            col_names = np.asarray(parts.col_names, dtype=object)
        if parts.row_names is None:
            row_names = np.full(data.shape[0], "", dtype=object)
        else:
            row_names = np.asarray(parts.row_names, dtype=object)

        assert len(col_names) == data.shape[1]
        assert len(row_names) == data.shape[0]

        for i, rowitem in enumerate(parts.rows):
            if rowitem.title:
                item = QGraphicsSimpleTextItem(rowitem.title, parent=self)
                item.setTransform(item.transform().rotate(-90))
                item = SimpleLayoutItem(item, parent=grid, anchor=(0, 1),
                                        anchorItem=(0, 0))
                item.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Maximum)
                grid.addItem(item, Row0 + i, self.GroupTitleColumn,
                             alignment=Qt.AlignCenter)
            if rowitem.cluster:
                dendrogram = DendrogramWidget(
                    parent=self,
                    selectionMode=DendrogramWidget.NoSelection,
                    hoverHighlightEnabled=True,
                )
                dendrogram.set_root(rowitem.cluster)
                dendrogram.setMaximumWidth(100)
                dendrogram.setMinimumWidth(100)
                # Ignore dendrogram vertical size hint (heatmap's size
                # should define the  row's vertical size).
                dendrogram.setSizePolicy(
                    QSizePolicy.Expanding, QSizePolicy.Ignored)
                dendrogram.itemClicked.connect(
                    lambda item, partindex=i:
                    self.__select_by_cluster(item, partindex)
                )
                grid.addItem(dendrogram, Row0 + i, DendrogramColumn)
                row_dendrograms[i] = dendrogram

        for j, colitem in enumerate(parts.columns):
            if colitem.title:
                item = SimpleLayoutItem(
                    QGraphicsSimpleTextItem(colitem.title, parent=self),
                    parent=grid, anchor=(0.5, 0.5), anchorItem=(0.5, 0.5)
                )
                item.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
                grid.addItem(item, self.GroupTitleRow, Col0 + 2 * j + 1)

            if colitem.cluster:
                dendrogram = DendrogramWidget(
                    parent=self,
                    orientation=DendrogramWidget.Top,
                    selectionMode=DendrogramWidget.NoSelection,
                    hoverHighlightEnabled=False
                )
                dendrogram.set_root(colitem.cluster)
                dendrogram.setMaximumHeight(100)
                dendrogram.setMinimumHeight(100)
                # Ignore dendrogram horizontal size hint (heatmap's width
                # should define the column width).
                dendrogram.setSizePolicy(
                    QSizePolicy.Ignored, QSizePolicy.Expanding)
                grid.addItem(dendrogram, DendrogramRow, Col0 + 2 * j + 1)
                column_dendrograms[j] = dendrogram

        heatmap_widgets = []
        for i in range(N):
            heatmap_row = []
            for j in range(M):
                row_ix = parts.rows[i].normalized_indices
                col_ix = parts.columns[j].normalized_indices
                X_part = data[np.ix_(row_ix, col_ix)]
                hw = GraphicsHeatmapWidget(
                    aspectRatioMode=self.__aspectRatioMode,
                    data=X_part, span=parts.span, colormap=colormap,
                )
                sp = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
                sp.setHeightForWidth(True)
                hw.setSizePolicy(sp)

                avgimg = GraphicsHeatmapWidget(
                    data=np.nanmean(X_part, axis=1, keepdims=True),
                    span=parts.span, colormap=colormap,
                    visible=self.__averagesVisible,
                    minimumSize=QSizeF(5, -1)
                )
                avgimg.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Ignored)
                grid.addItem(avgimg, Row0 + i, Col0 + 2 * j)
                grid.addItem(hw, Row0 + i, Col0 + 2 * j + 1)

                heatmap_row.append(hw)
            heatmap_widgets.append(heatmap_row)

        for j in range(M):
            grid.setColumnStretchFactor(Col0 + 2 * j, 1)
            grid.setColumnStretchFactor(
                Col0 + 2 * j + 1, parts.columns[j].size)
        grid.setColumnStretchFactor(RightLabelColumn - 1, 1)

        for i in range(N):
            grid.setRowStretchFactor(Row0 + i, parts.rows[i].size)

        row_annotation_widgets = []
        col_annotation_widgets = []
        col_annotation_widgets_top = []
        col_annotation_widgets_bottom = []

        for i, rowitem in enumerate(parts.rows):
            # Right row annotations
            indices = np.asarray(rowitem.normalized_indices, dtype=np.intp)
            labels = row_names[indices]
            labelslist = TextListWidget(
                items=labels, parent=self, orientation=Qt.Vertical,
                alignment=Qt.AlignLeft | Qt.AlignVCenter,
                sizePolicy=QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Ignored),
                autoScale=True,
                objectName="row-labels-right"
            )
            labelslist.setMaximumWidth(300)
            rowauxsidecolor = GraphicsPixmapWidget(
                parent=self, visible=False,
                scaleContents=True, aspectMode=Qt.IgnoreAspectRatio,
                sizePolicy=QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Ignored),
                minimumSize=QSizeF(10, -1)
            )
            grid.addItem(rowauxsidecolor, Row0 + i, RightLabelColumn - 1)
            grid.addItem(labelslist, Row0 + i, RightLabelColumn, Qt.AlignLeft)
            row_annotation_widgets.append(labelslist)
            right_side_colors[i] = rowauxsidecolor

        for j, colitem in enumerate(parts.columns):
            # Top attr annotations
            indices = np.asarray(colitem.normalized_indices, dtype=np.intp)
            labels = col_names[indices]
            sp = QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
            sp.setHeightForWidth(True)
            labelslist = TextListWidget(
                items=labels, parent=self,
                alignment=Qt.AlignLeft | Qt.AlignVCenter,
                orientation=Qt.Horizontal,
                autoScale=True,
                sizePolicy=sp,
                visible=self.__columnLabelPosition & Position.Top,
                objectName="column-labels-top",
            )
            colauxsidecolor = GraphicsPixmapWidget(
                parent=self, visible=False,
                scaleContents=True, aspectMode=Qt.IgnoreAspectRatio,
                sizePolicy=QSizePolicy(QSizePolicy.Ignored,
                                       QSizePolicy.Maximum),
                minimumSize=QSizeF(-1, 10)
            )

            grid.addItem(labelslist, TopLabelsRow, Col0 + 2 * j + 1,
                         Qt.AlignBottom | Qt.AlignLeft)
            grid.addItem(colauxsidecolor, TopAnnotationRow, Col0 + 2 * j + 1)
            col_annotation_widgets.append(labelslist)
            col_annotation_widgets_top.append(labelslist)
            top_side_colors[j] = colauxsidecolor

            # Bottom attr annotations
            labelslist = TextListWidget(
                items=labels, parent=self,
                alignment=Qt.AlignRight | Qt.AlignVCenter,
                orientation=Qt.Horizontal,
                autoScale=True,
                sizePolicy=sp,
                visible=self.__columnLabelPosition & Position.Bottom,
                objectName="column-labels-bottom",
            )
            grid.addItem(labelslist, BottomLabelsRow, Col0 + 2 * j + 1)
            col_annotation_widgets.append(labelslist)
            col_annotation_widgets_bottom.append(labelslist)

        row_color_annotation_header = QGraphicsSimpleTextItem("", self)
        row_color_annotation_header.setTransform(
            row_color_annotation_header.transform().rotate(-90))

        grid.addItem(SimpleLayoutItem(
            row_color_annotation_header, anchor=(0, 1),
            aspectMode=Qt.KeepAspectRatio,
            sizePolicy=QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred),
            ),
            0, RightLabelColumn - 1, self.TopLabelsRow + 1, 1,
            alignment=Qt.AlignBottom
        )

        col_color_annotation_header = QGraphicsSimpleTextItem("", self)
        grid.addItem(SimpleLayoutItem(
            col_color_annotation_header, anchor=(1, 1), anchorItem=(1, 1),
            aspectMode=Qt.KeepAspectRatio,
            sizePolicy=QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed),
        ),
            TopAnnotationRow, 0, 1, Col0, alignment=Qt.AlignRight
        )

        legend = GradientLegendWidget(
            parts.span[0], parts.span[1],
            colormap,
            parent=self,
            minimumSize=QSizeF(100, 20),
            visible=self.__legendVisible,
            sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        )
        legend.setMaximumWidth(300)
        grid.addItem(legend, self.LegendRow, self.LegendCol, 1, M * 2 - 1)

        def container(parent=None, orientation=Qt.Horizontal, margin=0, spacing=0, **kwargs):
            widget = QGraphicsWidget(**kwargs)
            layout = QGraphicsLinearLayout(orientation)
            layout.setContentsMargins(margin, margin, margin, margin)
            layout.setSpacing(spacing)
            widget.setLayout(layout)
            if parent is not None:
                widget.setParentItem(parent)

            return widget
        # Container for color annotation legends
        legend_container = container(
            spacing=3,
            sizePolicy=QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed),
            visible=False, objectName="annotation-legend-container"
        )
        legend_container_rows = container(
            parent=legend_container,
            sizePolicy=QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed),
            visible=False, objectName="row-annotation-legend-container"
        )
        legend_container_cols = container(
            parent=legend_container,
            sizePolicy=QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed),
            visible=False, objectName="col-annotation-legend-container"
        )
        # ? keep refs to child containers; segfault in scene.clear() ?
        legend_container._refs = (legend_container_rows, legend_container_cols)
        legend_container.layout().addItem(legend_container_rows)
        legend_container.layout().addItem(legend_container_cols)

        grid.addItem(legend_container, BottomLabelsRow + 1, Col0 + 1, 1, M * 2 - 1,
                     alignment=Qt.AlignRight)

        self.heatmap_widget_grid = heatmap_widgets
        self.row_annotation_widgets = row_annotation_widgets
        self.col_annotation_widgets = col_annotation_widgets
        self.col_annotation_widgets_top = col_annotation_widgets_top
        self.col_annotation_widgets_bottom = col_annotation_widgets_bottom
        self.col_dendrograms = column_dendrograms
        self.row_dendrograms = row_dendrograms
        self.right_side_colors = right_side_colors
        self.top_side_colors = top_side_colors
        self.heatmap_colormap_legend = legend
        self.bottom_legend_container = legend_container
        self.parts = parts
        self.__selection_manager.set_heatmap_widgets(heatmap_widgets)
def setHeatmaps ( self , parts : 'Parts' ) -> None : self . clear ( ) grid = self . __layout N , M = len ( parts . rows ) , len ( parts . columns ) # Start row/column where the heatmap items are inserted # (after the titles/legends/dendrograms) Row0 = self . Row0 Col0 = self . Col0 # The column for the vertical dendrograms DendrogramColumn = self . DendrogramColumn # The row for the horizontal dendrograms DendrogramRow = self . DendrogramRow RightLabelColumn = Col0 + 2 * M + 1 TopAnnotationRow = self . TopAnnotationRow TopLabelsRow = self . TopLabelsRow BottomLabelsRow = Row0 + N colormap = self . __colormap column_dendrograms : List [ Optional [ DendrogramWidget ] ] = [ None ] * M row_dendrograms : List [ Optional [ DendrogramWidget ] ] = [ None ] * N right_side_colors : List [ Optional [ GraphicsPixmapWidget ] ] = [ None ] * N top_side_colors : List [ Optional [ GraphicsPixmapWidget ] ] = [ None ] * M data = parts . data if parts . col_names is None : col_names = np . full ( data . shape [ 1 ] , "" , dtype = object ) else : col_names = np . asarray ( parts . col_names , dtype = object ) if parts . row_names is None : row_names = np . full ( data . shape [ 0 ] , "" , dtype = object ) else : row_names = np . asarray ( parts . row_names , dtype = object ) assert len ( col_names ) == data . shape [ 1 ] assert len ( row_names ) == data . shape [ 0 ] for i , rowitem in enumerate ( parts . rows ) : if rowitem . title : item = QGraphicsSimpleTextItem ( rowitem . title , parent = self ) item . setTransform ( item . transform ( ) . rotate ( - 90 ) ) item = SimpleLayoutItem ( item , parent = grid , anchor = ( 0 , 1 ) , anchorItem = ( 0 , 0 ) ) item . setSizePolicy ( QSizePolicy . Fixed , QSizePolicy . Maximum ) grid . addItem ( item , Row0 + i , self . GroupTitleColumn , alignment = Qt . AlignCenter ) if rowitem . cluster : dendrogram = DendrogramWidget ( parent = self , selectionMode = DendrogramWidget . NoSelection , hoverHighlightEnabled = True , ) dendrogram . set_root ( rowitem . cluster ) dendrogram . setMaximumWidth ( 100 ) dendrogram . setMinimumWidth ( 100 ) # Ignore dendrogram vertical size hint (heatmap's size # should define the  row's vertical size). dendrogram . setSizePolicy ( QSizePolicy . Expanding , QSizePolicy . Ignored ) dendrogram . itemClicked . connect ( lambda item , partindex = i : self . __select_by_cluster ( item , partindex ) ) grid . addItem ( dendrogram , Row0 + i , DendrogramColumn ) row_dendrograms [ i ] = dendrogram for j , colitem in enumerate ( parts . columns ) : if colitem . title : item = SimpleLayoutItem ( QGraphicsSimpleTextItem ( colitem . title , parent = self ) , parent = grid , anchor = ( 0.5 , 0.5 ) , anchorItem = ( 0.5 , 0.5 ) ) item . setSizePolicy ( QSizePolicy . Preferred , QSizePolicy . Fixed ) grid . addItem ( item , self . GroupTitleRow , Col0 + 2 * j + 1 ) if colitem . cluster : dendrogram = DendrogramWidget ( parent = self , orientation = DendrogramWidget . Top , selectionMode = DendrogramWidget . NoSelection , hoverHighlightEnabled = False ) dendrogram . set_root ( colitem . cluster ) dendrogram . setMaximumHeight ( 100 ) dendrogram . setMinimumHeight ( 100 ) # Ignore dendrogram horizontal size hint (heatmap's width # should define the column width). dendrogram . setSizePolicy ( QSizePolicy . Ignored , QSizePolicy . Expanding ) grid . addItem ( dendrogram , DendrogramRow , Col0 + 2 * j + 1 ) column_dendrograms [ j ] = dendrogram heatmap_widgets = [ ] for i in range ( N ) : heatmap_row = [ ] for j in range ( M ) : row_ix = parts . rows [ i ] . normalized_indices col_ix = parts . columns [ j ] . normalized_indices X_part = data [ np . ix_ ( row_ix , col_ix ) ] hw = GraphicsHeatmapWidget ( aspectRatioMode = self . __aspectRatioMode , data = X_part , span = parts . span , colormap = colormap , ) sp = QSizePolicy ( QSizePolicy . Preferred , QSizePolicy . Preferred ) sp . setHeightForWidth ( True ) hw . setSizePolicy ( sp ) avgimg = GraphicsHeatmapWidget ( data = np . nanmean ( X_part , axis = 1 , keepdims = True ) , span = parts . span , colormap = colormap , visible = self . __averagesVisible , minimumSize = QSizeF ( 5 , - 1 ) ) avgimg . setSizePolicy ( QSizePolicy . Preferred , QSizePolicy . Ignored ) grid . addItem ( avgimg , Row0 + i , Col0 + 2 * j ) grid . addItem ( hw , Row0 + i , Col0 + 2 * j + 1 ) heatmap_row . append ( hw ) heatmap_widgets . append ( heatmap_row ) for j in range ( M ) : grid . setColumnStretchFactor ( Col0 + 2 * j , 1 ) grid . setColumnStretchFactor ( Col0 + 2 * j + 1 , parts . columns [ j ] . size ) grid . setColumnStretchFactor ( RightLabelColumn - 1 , 1 ) for i in range ( N ) : grid . setRowStretchFactor ( Row0 + i , parts . rows [ i ] . size ) row_annotation_widgets = [ ] col_annotation_widgets = [ ] col_annotation_widgets_top = [ ] col_annotation_widgets_bottom = [ ] for i , rowitem in enumerate ( parts . rows ) : # Right row annotations indices = np . asarray ( rowitem . normalized_indices , dtype = np . intp ) labels = row_names [ indices ] labelslist = TextListWidget ( items = labels , parent = self , orientation = Qt . Vertical , alignment = Qt . AlignLeft | Qt . AlignVCenter , sizePolicy = QSizePolicy ( QSizePolicy . Fixed , QSizePolicy . Ignored ) , autoScale = True , objectName = "row-labels-right" ) labelslist . setMaximumWidth ( 300 ) rowauxsidecolor = GraphicsPixmapWidget ( parent = self , visible = False , scaleContents = True , aspectMode = Qt . IgnoreAspectRatio , sizePolicy = QSizePolicy ( QSizePolicy . Maximum , QSizePolicy . Ignored ) , minimumSize = QSizeF ( 10 , - 1 ) ) grid . addItem ( rowauxsidecolor , Row0 + i , RightLabelColumn - 1 ) grid . addItem ( labelslist , Row0 + i , RightLabelColumn , Qt . AlignLeft ) row_annotation_widgets . append ( labelslist ) right_side_colors [ i ] = rowauxsidecolor for j , colitem in enumerate ( parts . columns ) : # Top attr annotations indices = np . asarray ( colitem . normalized_indices , dtype = np . intp ) labels = col_names [ indices ] sp = QSizePolicy ( QSizePolicy . Ignored , QSizePolicy . Fixed ) sp . setHeightForWidth ( True ) labelslist = TextListWidget ( items = labels , parent = self , alignment = Qt . AlignLeft | Qt . AlignVCenter , orientation = Qt . Horizontal , autoScale = True , sizePolicy = sp , visible = self . __columnLabelPosition & Position . Top , objectName = "column-labels-top" , ) colauxsidecolor = GraphicsPixmapWidget ( parent = self , visible = False , scaleContents = True , aspectMode = Qt . IgnoreAspectRatio , sizePolicy = QSizePolicy ( QSizePolicy . Ignored , QSizePolicy . Maximum ) , minimumSize = QSizeF ( - 1 , 10 ) ) grid . addItem ( labelslist , TopLabelsRow , Col0 + 2 * j + 1 , Qt . AlignBottom | Qt . AlignLeft ) grid . addItem ( colauxsidecolor , TopAnnotationRow , Col0 + 2 * j + 1 ) col_annotation_widgets . append ( labelslist ) col_annotation_widgets_top . append ( labelslist ) top_side_colors [ j ] = colauxsidecolor # Bottom attr annotations labelslist = TextListWidget ( items = labels , parent = self , alignment = Qt . AlignRight | Qt . AlignVCenter , orientation = Qt . Horizontal , autoScale = True , sizePolicy = sp , visible = self . __columnLabelPosition & Position . Bottom , objectName = "column-labels-bottom" , ) grid . addItem ( labelslist , BottomLabelsRow , Col0 + 2 * j + 1 ) col_annotation_widgets . append ( labelslist ) col_annotation_widgets_bottom . append ( labelslist ) row_color_annotation_header = QGraphicsSimpleTextItem ( "" , self ) row_color_annotation_header . setTransform ( row_color_annotation_header . transform ( ) . rotate ( - 90 ) ) grid . addItem ( SimpleLayoutItem ( row_color_annotation_header , anchor = ( 0 , 1 ) , aspectMode = Qt . KeepAspectRatio , sizePolicy = QSizePolicy ( QSizePolicy . Fixed , QSizePolicy . Preferred ) , ) , 0 , RightLabelColumn - 1 , self . TopLabelsRow + 1 , 1 , alignment = Qt . AlignBottom ) col_color_annotation_header = QGraphicsSimpleTextItem ( "" , self ) grid . addItem ( SimpleLayoutItem ( col_color_annotation_header , anchor = ( 1 , 1 ) , anchorItem = ( 1 , 1 ) , aspectMode = Qt . KeepAspectRatio , sizePolicy = QSizePolicy ( QSizePolicy . Fixed , QSizePolicy . Fixed ) , ) , TopAnnotationRow , 0 , 1 , Col0 , alignment = Qt . AlignRight ) legend = GradientLegendWidget ( parts . span [ 0 ] , parts . span [ 1 ] , colormap , parent = self , minimumSize = QSizeF ( 100 , 20 ) , visible = self . __legendVisible , sizePolicy = QSizePolicy ( QSizePolicy . Ignored , QSizePolicy . Fixed ) ) legend . setMaximumWidth ( 300 ) grid . addItem ( legend , self . LegendRow , self . LegendCol , 1 , M * 2 - 1 ) def container ( parent = None , orientation = Qt . Horizontal , margin = 0 , spacing = 0 , * * kwargs ) : widget = QGraphicsWidget ( * * kwargs ) layout = QGraphicsLinearLayout ( orientation ) layout . setContentsMargins ( margin , margin , margin , margin ) layout . setSpacing ( spacing ) widget . setLayout ( layout ) if parent is not None : widget . setParentItem ( parent ) return widget # Container for color annotation legends legend_container = container ( spacing = 3 , sizePolicy = QSizePolicy ( QSizePolicy . Maximum , QSizePolicy . Fixed ) , visible = False , objectName = "annotation-legend-container" ) legend_container_rows = container ( parent = legend_container , sizePolicy = QSizePolicy ( QSizePolicy . Maximum , QSizePolicy . Fixed ) , visible = False , objectName = "row-annotation-legend-container" ) legend_container_cols = container ( parent = legend_container , sizePolicy = QSizePolicy ( QSizePolicy . Maximum , QSizePolicy . Fixed ) , visible = False , objectName = "col-annotation-legend-container" ) # ? keep refs to child containers; segfault in scene.clear() ? legend_container . _refs = ( legend_container_rows , legend_container_cols ) legend_container . layout ( ) . addItem ( legend_container_rows ) legend_container . layout ( ) . addItem ( legend_container_cols ) grid . addItem ( legend_container , BottomLabelsRow + 1 , Col0 + 1 , 1 , M * 2 - 1 , alignment = Qt . AlignRight ) self . heatmap_widget_grid = heatmap_widgets self . row_annotation_widgets = row_annotation_widgets self . col_annotation_widgets = col_annotation_widgets self . col_annotation_widgets_top = col_annotation_widgets_top self . col_annotation_widgets_bottom = col_annotation_widgets_bottom self . col_dendrograms = column_dendrograms self . row_dendrograms = row_dendrograms self . right_side_colors = right_side_colors self . top_side_colors = top_side_colors self . heatmap_colormap_legend = legend self . bottom_legend_container = legend_container self . parts = parts self . __selection_manager . set_heatmap_widgets ( heatmap_widgets )