Skip to content

napari_ndev._plate_mapper #

PlateMapper #

A class for creating and manipulating plate maps.

Attributes:

  • plate_size (int) –

    The size of the plate (e.g., 96, 384).

  • wells (dict) –

    A dictionary mapping plate sizes to the number of rows and columns.

  • plate_map (DataFrame) –

    The plate map DataFrame with well labels.

  • plate_map_pivot (DataFrame) –

    The wide-formatted plate map DataFrame with treatments as columns.

Methods:

  • __init__

    Initializes a PlateMapper object.

  • create_empty_plate_map

    Creates an empty plate map DataFrame for a given plate size.

  • assign_treatments

    Assigns treatments to specific wells in a plate map.

  • get_pivoted_plate_map

    Pivots a plate map DataFrame to create a wide-formatted DataFrame with a single treatment as columns.

  • get_styled_plate_map

    Styles a plate map DataFrame with different background colors for each unique value.

Source code in src/napari_ndev/_plate_mapper.py
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
class PlateMapper:
    """
    A class for creating and manipulating plate maps.

    Attributes
    ----------
    plate_size : int
        The size of the plate (e.g., 96, 384).
    wells : dict
        A dictionary mapping plate sizes to the number of rows and columns.
    plate_map : pandas.DataFrame
        The plate map DataFrame with well labels.
    plate_map_pivot : pandas.DataFrame
        The wide-formatted plate map DataFrame with treatments as columns.

    Methods
    -------
    __init__(plate_size=96)
        Initializes a PlateMapper object.
    create_empty_plate_map()
        Creates an empty plate map DataFrame for a given plate size.
    assign_treatments(treatments)
        Assigns treatments to specific wells in a plate map.
    get_pivoted_plate_map(treatment)
        Pivots a plate map DataFrame to create a wide-formatted DataFrame with a single treatment as columns.
    get_styled_plate_map(treatment, palette='colorblind')
        Styles a plate map DataFrame with different background colors for each unique value.

    """

    def __init__(self, plate_size=96):
        """
        Initialize a PlateMapper object.

        Parameters
        ----------
        plate_size : int, optional
            The size of the plate. Defaults to 96.

        """
        self.plate_size = plate_size
        self.wells = {
            6: (2, 3),
            12: (3, 4),
            24: (4, 6),
            48: (6, 8),
            96: (8, 12),
            384: (16, 24),
        }
        self.plate_map = self.create_empty_plate_map()
        self.plate_map_pivot = None

    def create_empty_plate_map(self):
        """
        Create an empty plate map DataFrame for a given plate size.

        Returns
        -------
        pandas.DataFrame
            The empty plate map DataFrame with well labels.

        """
        num_rows, num_columns = self.wells[self.plate_size]

        row_labels = list(string.ascii_uppercase)[:num_rows]
        column_labels = list(range(1, num_columns + 1))

        well_rows = row_labels * num_columns
        well_rows.sort()  # needed to sort the rows correctly
        well_columns = column_labels * num_rows

        well_labels_dict = {'row': well_rows, 'column': well_columns}

        plate_map_df = pd.DataFrame(well_labels_dict)

        plate_map_df['well_id'] = plate_map_df['row'] + plate_map_df[
            'column'
        ].astype(str)
        self.plate_map = plate_map_df
        return plate_map_df

    def assign_treatments(self, treatments):
        """
        Assign treatments to specific wells in a plate map.

        Parameters
        ----------
        treatments : dict
            A dictionary mapping treatments to conditions and well ranges.

        Returns
        -------
        pandas.DataFrame
            The updated plate map with treatments assigned to specific wells.

        """
        for treatment, conditions in treatments.items():
            for condition, wells in conditions.items():
                for well in wells:
                    if ':' in well:
                        start, end = well.split(':')
                        start_row, start_col = start[0], int(start[1:])
                        end_row, end_col = end[0], int(end[1:])
                        well_condition = (
                            (self.plate_map['row'] >= start_row)
                            & (self.plate_map['row'] <= end_row)
                            & (self.plate_map['column'] >= start_col)
                            & (self.plate_map['column'] <= end_col)
                        )
                    else:
                        row, col = well[0], int(well[1:])
                        well_condition = (self.plate_map['row'] == row) & (
                            self.plate_map['column'] == col
                        )

                    self.plate_map.loc[well_condition, treatment] = condition
        return self.plate_map

    def get_pivoted_plate_map(self, treatment):
        """
        Pivot a plate map DataFrame to create a wide-formatted DataFrame with a single treatment as columns.

        Parameters
        ----------
        treatment : str
            The column name of the treatment variable in the plate map DataFrame.

        Returns
        -------
        pandas.DataFrame
            The wide-formatted plate map DataFrame with treatments as columns.

        """
        plate_map_pivot = self.plate_map.pivot(
            index='row', columns='column', values=treatment
        )
        self.plate_map_pivot = plate_map_pivot
        return plate_map_pivot

    def get_styled_plate_map(self, treatment, palette='colorblind'):
        """
        Style a plate map with background colors for each unique value.

        Parameters
        ----------
        treatment : str
            The column name of the treatment variable in the plate map DataFrame.
        palette : str or list, optional
            The color palette to use for styling. Defaults to 'colorblind'.

        Returns
        -------
        pandas.io.formats.style.Styler
            The styled plate map DataFrame with different background colors for each unique value.

        """
        from seaborn import color_palette

        self.plate_map_pivot = self.get_pivoted_plate_map(treatment)

        unique_values = pd.unique(self.plate_map_pivot.values.flatten())
        unique_values = unique_values[pd.notna(unique_values)]

        color_palette_hex = color_palette(palette).as_hex()
        # Create an infinite iterator that cycles through the palette
        palette_cycle = itertools.cycle(color_palette_hex)
        # Use next() to get the next color
        color_dict = {value: next(palette_cycle) for value in unique_values}

        def get_background_color(value):
            if pd.isna(value):
                return ''
            return f'background-color: {color_dict[value]}'

        plate_map_styled = (
            self.plate_map_pivot.style.applymap(get_background_color)
            .set_caption(f'{treatment} Plate Map')
            .format(lambda x: '' if pd.isna(x) else x)
        )

        return plate_map_styled

__init__ #

__init__(plate_size=96)

Initialize a PlateMapper object.

Parameters:

  • plate_size #

    (int, default: 96 ) –

    The size of the plate. Defaults to 96.

Source code in src/napari_ndev/_plate_mapper.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def __init__(self, plate_size=96):
    """
    Initialize a PlateMapper object.

    Parameters
    ----------
    plate_size : int, optional
        The size of the plate. Defaults to 96.

    """
    self.plate_size = plate_size
    self.wells = {
        6: (2, 3),
        12: (3, 4),
        24: (4, 6),
        48: (6, 8),
        96: (8, 12),
        384: (16, 24),
    }
    self.plate_map = self.create_empty_plate_map()
    self.plate_map_pivot = None

assign_treatments #

assign_treatments(treatments)

Assign treatments to specific wells in a plate map.

Parameters:

  • treatments #

    (dict) –

    A dictionary mapping treatments to conditions and well ranges.

Returns:

  • DataFrame

    The updated plate map with treatments assigned to specific wells.

Source code in src/napari_ndev/_plate_mapper.py
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
def assign_treatments(self, treatments):
    """
    Assign treatments to specific wells in a plate map.

    Parameters
    ----------
    treatments : dict
        A dictionary mapping treatments to conditions and well ranges.

    Returns
    -------
    pandas.DataFrame
        The updated plate map with treatments assigned to specific wells.

    """
    for treatment, conditions in treatments.items():
        for condition, wells in conditions.items():
            for well in wells:
                if ':' in well:
                    start, end = well.split(':')
                    start_row, start_col = start[0], int(start[1:])
                    end_row, end_col = end[0], int(end[1:])
                    well_condition = (
                        (self.plate_map['row'] >= start_row)
                        & (self.plate_map['row'] <= end_row)
                        & (self.plate_map['column'] >= start_col)
                        & (self.plate_map['column'] <= end_col)
                    )
                else:
                    row, col = well[0], int(well[1:])
                    well_condition = (self.plate_map['row'] == row) & (
                        self.plate_map['column'] == col
                    )

                self.plate_map.loc[well_condition, treatment] = condition
    return self.plate_map

create_empty_plate_map #

create_empty_plate_map()

Create an empty plate map DataFrame for a given plate size.

Returns:

  • DataFrame

    The empty plate map DataFrame with well labels.

Source code in src/napari_ndev/_plate_mapper.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
def create_empty_plate_map(self):
    """
    Create an empty plate map DataFrame for a given plate size.

    Returns
    -------
    pandas.DataFrame
        The empty plate map DataFrame with well labels.

    """
    num_rows, num_columns = self.wells[self.plate_size]

    row_labels = list(string.ascii_uppercase)[:num_rows]
    column_labels = list(range(1, num_columns + 1))

    well_rows = row_labels * num_columns
    well_rows.sort()  # needed to sort the rows correctly
    well_columns = column_labels * num_rows

    well_labels_dict = {'row': well_rows, 'column': well_columns}

    plate_map_df = pd.DataFrame(well_labels_dict)

    plate_map_df['well_id'] = plate_map_df['row'] + plate_map_df[
        'column'
    ].astype(str)
    self.plate_map = plate_map_df
    return plate_map_df

get_pivoted_plate_map #

get_pivoted_plate_map(treatment)

Pivot a plate map DataFrame to create a wide-formatted DataFrame with a single treatment as columns.

Parameters:

  • treatment #

    (str) –

    The column name of the treatment variable in the plate map DataFrame.

Returns:

  • DataFrame

    The wide-formatted plate map DataFrame with treatments as columns.

Source code in src/napari_ndev/_plate_mapper.py
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
def get_pivoted_plate_map(self, treatment):
    """
    Pivot a plate map DataFrame to create a wide-formatted DataFrame with a single treatment as columns.

    Parameters
    ----------
    treatment : str
        The column name of the treatment variable in the plate map DataFrame.

    Returns
    -------
    pandas.DataFrame
        The wide-formatted plate map DataFrame with treatments as columns.

    """
    plate_map_pivot = self.plate_map.pivot(
        index='row', columns='column', values=treatment
    )
    self.plate_map_pivot = plate_map_pivot
    return plate_map_pivot

get_styled_plate_map #

get_styled_plate_map(treatment, palette='colorblind')

Style a plate map with background colors for each unique value.

Parameters:

  • treatment #

    (str) –

    The column name of the treatment variable in the plate map DataFrame.

  • palette #

    (str or list, default: 'colorblind' ) –

    The color palette to use for styling. Defaults to 'colorblind'.

Returns:

  • Styler

    The styled plate map DataFrame with different background colors for each unique value.

Source code in src/napari_ndev/_plate_mapper.py
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
def get_styled_plate_map(self, treatment, palette='colorblind'):
    """
    Style a plate map with background colors for each unique value.

    Parameters
    ----------
    treatment : str
        The column name of the treatment variable in the plate map DataFrame.
    palette : str or list, optional
        The color palette to use for styling. Defaults to 'colorblind'.

    Returns
    -------
    pandas.io.formats.style.Styler
        The styled plate map DataFrame with different background colors for each unique value.

    """
    from seaborn import color_palette

    self.plate_map_pivot = self.get_pivoted_plate_map(treatment)

    unique_values = pd.unique(self.plate_map_pivot.values.flatten())
    unique_values = unique_values[pd.notna(unique_values)]

    color_palette_hex = color_palette(palette).as_hex()
    # Create an infinite iterator that cycles through the palette
    palette_cycle = itertools.cycle(color_palette_hex)
    # Use next() to get the next color
    color_dict = {value: next(palette_cycle) for value in unique_values}

    def get_background_color(value):
        if pd.isna(value):
            return ''
        return f'background-color: {color_dict[value]}'

    plate_map_styled = (
        self.plate_map_pivot.style.applymap(get_background_color)
        .set_caption(f'{treatment} Plate Map')
        .format(lambda x: '' if pd.isna(x) else x)
    )

    return plate_map_styled