Example #1
0
File: box.py Project: gogrean/PyXel
 def distribute_pixels(self, edges, length, width):
     corners = self.get_corners()
     reg_path = Path(corners)
     # Get region boundaries.
     bounds = reg_path.get_extents().get_points()
     [[x_min_bound, y_min_bound], [x_max_bound, y_max_bound]] = bounds
     # For cases when the boundary pixels are not integers:
     x_min_bound = floor(x_min_bound)
     y_min_bound = floor(y_min_bound)
     x_max_bound = ceil(x_max_bound)
     y_max_bound = ceil(y_max_bound)
     pixels_in_bins = []
     for x in range(max(0, x_min_bound), min(x_max_bound+1, width)):
         for y in range(max(0, y_min_bound), min(y_max_bound+1, length)):
             if reg_path.contains_point((x, y)):
                 x_nonrotated, y_nonrotated = rotate_point(self.x0, self.y0,
                                                           x - self.x0,
                                                           y - self.y0,
                                                           -self.angle)
                 dist_from_box_bottom = self.height/2. - \
                                        (self.y0 - y_nonrotated)
                 for i, edge in enumerate(edges[1:]):
                     if edge > dist_from_box_bottom:
                         pixels_in_bins.append((y, x, i))
                         break
     return pixels_in_bins
def init():
    """Initialization"""
    global config, first_names, last_names, aggregate_url, open_hds_connection, odk_connection
    global area_polygon, area_extent, locations_per_social_group, individuals_per_social_group
    global pop_size_baseline, site, min_age_head_of_social_group, proportion_females, birth_rate, death_rate
    global min_age_marriage
    with open(os.path.join(conf_dir, 'config.json')) as config_file:
        config = json.load(config_file)
    with open(os.path.join(conf_dir, 'site.json')) as site_file:
        site = json.load(site_file)
    open_hds_connection = MySQLdb.connect(host=config['open_hds_server']['db_host'],
                                          user=config['open_hds_server']['db_user'],
                                          passwd=config['open_hds_server']['db_password'],
                                          db=config['open_hds_server']['db_name'],
                                          cursorclass=MySQLdb.cursors.DictCursor)
    open_hds_connection.autocommit(True)
    odk_connection = MySQLdb.connect(host=config['odk_server']['db_host'],
                                     user=config['odk_server']['db_user'],
                                     passwd=config['odk_server']['db_password'],
                                     db=config['odk_server']['db_name'],
                                     cursorclass=MySQLdb.cursors.DictCursor)
    odk_connection.autocommit(True)
    aggregate_url = config['odk_server']['aggregate_url']
    with open(os.path.join(conf_dir, 'firstnames.csv')) as f:
        first_names = list(f.read().splitlines(False))
    with open(os.path.join(conf_dir, 'lastnames.csv')) as f:
        last_names = list(f.read().splitlines(False))
    area_outline_vertices = []
    for point in site['general']['area_polygon']:
        area_outline_vertices.append(point)
    area_polygon = Path(area_outline_vertices)
    area_extent = area_polygon.get_extents().get_points()
    pop_size_baseline = site['general']['pop_size_baseline']
    locations_per_social_group = site['socialgroup']['locations_per_social_group']
    individuals_per_social_group = site['socialgroup']['individuals_per_social_group']
    min_age_head_of_social_group = site['socialgroup']['min_age_head']
    min_age_marriage = site['relationship']['min_age_marriage']
    proportion_females = 1 / (1 + site['general']['sex_ratio'])
    birth_rate = site['general']['birth_rate']
    death_rate = site['general']['death_rate']

    if config['general']['clean_db_on_init']:
        clean_db()
        create_fws(site['fieldworker'])
        create_location_hierarchy(site['locationhierarchy'])
Example #3
0
    def plot(self, ax: Axes) -> Axes:
        """Plot the curve."""
        xmin, xmax = ax.get_xlim()
        ymin, ymax = ax.get_ylim()
        if not self.x_data or not self.y_data or not _between_limits(
                self.x_data, self.y_data, xmin, xmax, ymin, ymax):
            self._print_err(
                '{} (label:{}) Not between limits ([{}, {}, {}, {}]) '
                '-> x:{}, y:{}'.format(self._type_curve, self._label, xmin,
                                       xmax, ymin, ymax, self.x_data,
                                       self.y_data))
            return ax

        if self._is_patch and self.y_data is not None:
            assert len(self.y_data) > 2
            verts = list(zip(self.x_data, self.y_data))
            codes = ([Path.MOVETO] + [Path.LINETO] * (len(self.y_data) - 2) +
                     [Path.CLOSEPOLY])
            path = Path(verts, codes)
            patch = patches.PathPatch(path, **self.style)
            ax.add_patch(patch)

            if self._label is not None:
                bbox_p = path.get_extents()
                text_x = .5 * (bbox_p.x0 + bbox_p.x1)
                text_y = .5 * (bbox_p.y0 + bbox_p.y1)
                style = {
                    'ha': 'center',
                    'va': 'center',
                    "backgroundcolor": [1, 1, 1, .4]
                }
                if 'edgecolor' in self.style:
                    style['color'] = mod_color(self.style['edgecolor'], -25)
                self._annotate_label(ax, self._label, text_x, text_y, 0, style)
        else:
            ax.plot(self.x_data, self.y_data, **self.style)
            if self._label is not None:
                self.add_label(ax)

        return ax
Example #4
0
    def plot(self, ax: Axes) -> Axes:
        """Plot the curve."""
        xmin, xmax = ax.get_xlim()
        ymin, ymax = ax.get_ylim()
        if (self.x_data is None or self.y_data is None or not _between_limits(
                self.x_data, self.y_data, xmin, xmax, ymin, ymax)):
            logging.info(
                f"{self._type_curve} (label:{self._label}) Not between limits "
                f"([{xmin}, {xmax}, {ymin}, {ymax}]) "
                f"-> x:{self.x_data}, y:{self.y_data}")
            return ax

        if self._is_patch and self.y_data is not None:
            assert len(self.y_data) > 2
            verts = list(zip(self.x_data, self.y_data))
            codes = ([Path.MOVETO] + [Path.LINETO] * (len(self.y_data) - 2) +
                     [Path.CLOSEPOLY])
            path = Path(verts, codes)
            patch = patches.PathPatch(path, **self.style)
            ax.add_patch(patch)

            if self._label is not None:
                bbox_p = path.get_extents()
                text_x = 0.5 * (bbox_p.x0 + bbox_p.x1)
                text_y = 0.5 * (bbox_p.y0 + bbox_p.y1)
                style = {
                    "ha": "center",
                    "va": "center",
                    "backgroundcolor": [1, 1, 1, 0.4],
                }
                if "edgecolor" in self.style:
                    style["color"] = mod_color(self.style["edgecolor"], -25)
                self._annotate_label(ax, self._label, text_x, text_y, 0, style)
        else:
            ax.plot(self.x_data, self.y_data, **self.style)
            if self._label is not None:
                self.add_label(ax)

        return ax
def get_nodule_mask(img, rois):
    """
    Given an image and its roi (list of contour boundary points), returns a
    2D binary mask for the image

    :param img: 2D numpy array of CT image
    :param rois: 1D numpy array of list of boundary points defining ROI
    returns: 2D numpy array of image's binary contour
    """
    x, y = np.mgrid[:img.shape[1], :img.shape[0]]

    # mesh grid to a list of points
    points = np.vstack((x.ravel(), y.ravel())).T

    # empty mask
    mask = np.zeros(img.shape[0] * img.shape[1])

    try:
        # iteratively add roi regions to mask
        for roi in rois:
            # from roi to a matplotlib path
            path = Path(roi)
            xmin, ymin, xmax, ymax = np.asarray(path.get_extents(),
                                                dtype=int).ravel()

            # add points to mask included in the path
            mask = np.logical_or(mask, np.array(path.contains_points(points)))

    # except if image is w/o ROIs (empty mask)
    except TypeError:
        pass

    # reshape mask
    mask = np.array([float(m) for m in mask])
    img_mask = mask.reshape(x.shape).T

    return img_mask
Example #6
0
 def __str__(self):
     if self.shape in ['rectangle', 'ellipse']:
         x, y, wid, hgt = self.geometry
         text = '{0}: ({1:.4G}, {2:.4G}), {3:.4G}, {4:.4G}'
         text = text.format(self.shape.capitalize(), x, y, wid, hgt)
     elif self.shape == 'lasso':
         if not self.geometry:
             return ''
         path = Path(self.geometry)
         extents = path.get_extents()
         x, y = extents.p0
         text = 'Lasso: ({0:.4G}, {1:.4G}), {2:.4G}, {3:.4G}'
         text = text.format(x, y, extents.width, extents.height)
     elif self.shape == 'line' and not self.data is None:
         p1, p2 = self.geometry
         if p1[0] > p2[0]:
             p1, p2 = p2, p1
         dx = p2[0] - p1[0]
         dy = p1[1] - p2[1]
         dist = np.hypot(dx, dy)
         angle = np.arctan2(dy, dx) * 180. / np.pi
         text = 'Line: {0:.4G}, {1} deg, ({2:.4G}, {3:.4G})'
         text = text.format(dist, int(angle), p1[0], p1[1])
     elif self.shape == 'point':
         x, y = self.geometry
         if not self.data is None:
             text = 'Point: {0:.4G} @ ({1:.4G}, {2:.4G})'
             try:
                 text = text.format(self.data[5, 5], x, y)
             except (ValueError, IndexError):
                 pass
         else:
             text = 'Point: ({0:.4G}, {1:.4G})'.format(x, y)
     else:
         text = object.__str__(self)
     return text
Example #7
0
def test_empty_closed_path():
    path = Path(np.zeros((0, 2)), closed=True)
    assert path.vertices.shape == (0, 2)
    assert path.codes is None
    assert_array_equal(path.get_extents().extents,
                       transforms.Bbox.null().extents)
def selectroi(img2):
    global img_formask
    global start
    global coordinates 
    global stop
    global grayscale
    
        
    img_formask = img2
#    img_formask = cv2.imread('Eyee.png',-1)
    if grayscale == 1:
        img_formask=cv2.cvtColor(img_formask,cv2.COLOR_BGR2GRAY)
    
        
    coordinates=[]         
    
    
    cv2.namedWindow('image')
    cv2.setMouseCallback('image',draw_circle)
    
    
    
    while(1):
        
        cv2.imshow('image',img_formask)
        k = cv2.waitKey(20) & 0xFF
        if (k == 27) or (stop==1) :
          #  print('i stopped sir')
            cv2.destroyAllWindows()
            break

    
    
                
    coordinates=np.asarray(coordinates)
    
    path = Path(coordinates)
    xmin, ymin, xmax, ymax = np.asarray(path.get_extents(), dtype=int).ravel()
    
    
    x, y = np.mgrid[:img.shape[1], :img.shape[0]]
    
    points = np.vstack((x.ravel(), y.ravel())).T
    
    
    mask = path.contains_points(points)
    path_points = points[np.where(mask)]
    
    
    img_mask = mask.reshape(x.shape).T
    
    img_mask1=img1 * img_mask[..., None]
    img_mask2=img_mask1
    if grayscale==1:
        limit=1
    else:
    
        limit=3
        
    for k in range(0,limit):
        
        for i in range(0,img_mask2.shape[0]):
            for j in range(0,img_mask2.shape[1]):
                if img_mask1[i,j,k] != 0:
                    img_mask2[i,j,k]=255
                else:
                    img_mask2[i,j,k]=0    
    

    return img_mask2
Example #9
0
def test_extents_with_ignored_codes(ignored_code):
    # Check that STOP and CLOSEPOLY points are ignored when calculating extents
    # of a path with only straight lines
    path = Path([[0, 0], [1, 1], [2, 2]],
                [Path.MOVETO, Path.MOVETO, ignored_code])
    assert np.all(path.get_extents().extents == (0., 0., 1., 1.))
plot_dims = np.r_[np.diff(ax.get_xbound()), np.diff(ax.get_ybound())]

# create MNE clipping mask
mne_path = TextPath((0, 0), 'MNE')
dims = mne_path.vertices.max(0) - mne_path.vertices.min(0)
vert = mne_path.vertices - dims / 2.
mult = (plot_dims / dims).min()
mult = [mult, -mult]  # y axis is inverted (origin at top left)
offset = plot_dims / 2. - center_fudge
mne_clip = Path(offset + vert * mult, mne_path.codes)
# apply clipping mask to field gradient and lines
im.set_clip_path(mne_clip, transform=im.get_transform())
for coll in cs.collections:
    coll.set_clip_path(mne_clip, transform=im.get_transform())
# get final position of clipping mask
mne_corners = mne_clip.get_extents().corners()

# add tagline
rcParams.update({'font.sans-serif': ['Cooper Hewitt'], 'font.weight': 'light'})
tag_path = TextPath((0, 0), 'MEG + EEG  ANALYSIS & VISUALIZATION')
dims = tag_path.vertices.max(0) - tag_path.vertices.min(0)
vert = tag_path.vertices - dims / 2.
mult = tagline_scale_fudge * (plot_dims / dims).min()
mult = [mult, -mult]  # y axis is inverted
offset = mne_corners[-1] - np.array([mne_clip.get_extents().size[0] / 2.,
                                     -dims[1]]) - tagline_offset_fudge
tag_clip = Path(offset + vert * mult, tag_path.codes)
tag_patch = PathPatch(tag_clip, facecolor='k', edgecolor='none', zorder=10)
ax.add_patch(tag_patch)
yl = ax.get_ylim()
yy = np.max([tag_clip.vertices.max(0)[-1],
Example #11
0
import pandas as pd
import scipy
import seaborn as sns

import bruno_util.plotting as bplt
figure_size = bplt.use_cell_style(mpl.rcParams)

km_color = sns.color_palette('colorblind')[0]
interior_color = sns.color_palette('colorblind')[1]
interior_linestyle = '-.'

# make cool legends where stair lines and straight lines are treated
# differently
stair_path = Path([[-1, -1], [-1 / 3, -1], [-1 / 3, 1], [1 / 3, 1],
                   [1 / 3, -1], [1, -1], [1, 1], [5 / 3, 1]])
bbox = stair_path.get_extents()
make_unit = Affine2D() \
        .translate(-bbox.x0, -bbox.y0) \
        .scale(1/bbox.width, 1/bbox.height)
stair_path = make_unit.transform_path(stair_path)


def _int_win_from_obs(obs, state):
    interior = obs.loc[(obs['state'] == state) &
                       (obs['wait_type'] == 'interior'),
                       ['wait_time', 'window_size']]
    return interior.wait_time.values, interior.window_size.values


def _ext_from_obs(obs, state):
    exterior = obs.loc[(obs['state'] == state)
Example #12
0
plot_dims = np.r_[np.diff(ax.get_xbound()), np.diff(ax.get_ybound())]

# create MNE clipping mask
mne_path = TextPath((0, 0), 'MNE')
dims = mne_path.vertices.max(0) - mne_path.vertices.min(0)
vert = mne_path.vertices - dims / 2.
mult = (plot_dims / dims).min()
mult = [mult, -mult]  # y axis is inverted (origin at top left)
offset = plot_dims / 2. - center_fudge
mne_clip = Path(offset + vert * mult, mne_path.codes)
# apply clipping mask to field gradient and lines
im.set_clip_path(mne_clip, transform=im.get_transform())
for coll in cs.collections:
    coll.set_clip_path(mne_clip, transform=im.get_transform())
# get final position of clipping mask
mne_corners = mne_clip.get_extents().corners()

# add tagline
rcParams.update({'font.sans-serif': ['Cooper Hewitt'], 'font.weight': 'light'})
tag_path = TextPath((0, 0), 'MEG + EEG  ANALYSIS & VISUALIZATION')
dims = tag_path.vertices.max(0) - tag_path.vertices.min(0)
vert = tag_path.vertices - dims / 2.
mult = tagline_scale_fudge * (plot_dims / dims).min()
mult = [mult, -mult]  # y axis is inverted
offset = mne_corners[-1] - np.array(
    [mne_clip.get_extents().size[0] / 2., -dims[1]]) - tagline_offset_fudge
tag_clip = Path(offset + vert * mult, tag_path.codes)
tag_patch = PathPatch(tag_clip, facecolor='k', edgecolor='none', zorder=10)
ax.add_patch(tag_patch)
yl = ax.get_ylim()
yy = np.max([tag_clip.vertices.max(0)[-1], tag_clip.vertices.min(0)[-1]])
            response = pbclient.update_app(app)
            check_api_error(response)
        except:
            format_error("pbclient.update_app", response)

    if args.create_tasks:
        response = pbclient.find_app(short_name='RuralGeolocator')
        app = response[0]
        app_id = app.id
        #polygon around area to be tasked, as list of (lat, long) lists
        rusingaOutlineData = json.load(open('data/area.json'))
        rusingaOutlineVertices = []
        for point in rusingaOutlineData:
            rusingaOutlineVertices.append(point)
        islandPolygon = Path(rusingaOutlineVertices)
        points = islandPolygon.get_extents().get_points()
        #The northern, southern, western, and eastern bounds of the area to work on.
        nb = points[1][0]
        wb = points[0][1]
        sb = points[0][0]
        eb = points[1][1]
        print (nb, wb, sb, eb)
        #Size of the tasks, into how many rows and columns should the area be divided.
        task_cols = 40
        task_rows = 30
        ns_step = (sb - nb) / task_cols
        we_step = (eb - wb) / task_rows
        task_counter = 0
        for row in range(task_rows):
            wbr = wb + row * we_step
            ebr = wb + (row + 1) * we_step
    (0.2, 1.),  # P1
    (1.0, 1.0),  # P2
    (1.5, 1.0),  # P3
    (1.7, 2.0)  # P4
]

codes = [
    Path.MOVETO,
    Path.CURVE3,
    Path.CURVE3,
    Path.CURVE3,
    Path.CURVE3,
]

path = Path(verts, codes)
print(path.get_extents())
fig = plt.figure()
ax = fig.add_subplot(111)
patch = patches.PathPatch(path, facecolor='none', lw=2)
ax.add_patch(patch)

xs, ys = zip(*verts)
print(*verts)
ax.plot(xs, ys, 'x--', lw=2, color='black', ms=10)

ax.text(-0.05, -0.05, 'P0')
ax.text(0.15, 1.05, 'P1')
ax.text(1.05, 0.85, 'P2')
ax.text(1.55, 1.05, 'P3')
ax.text(1.75, 1.05, 'P4')
Example #15
0
def sequence_logo(score_matrix,
                  order="value",
                  width=1.0,
                  ax=None,
                  sequence_type=Genome,
                  font_properties=None,
                  color_scheme=None,
                  **kwargs):
    """Plots a sequence logo for visualizing motifs.

    Parameters
    ----------
    score_matrix : np.ndarray
        An :math:`L \\times N` array (where :math:`L` is the length of
        the sequence, and :math:`N` is the size of the alphabet)
        containing the scores for each base occuring at each position.
    order : {'alpha', 'value'}
        The manner by which to sort the bases stacked at each position
        in the sequence logo plot.

            * 'alpha' - Bases go in the order they are found in the\
                      sequence alphabet.
            * 'value' - Bases go in the order of their value, with the\
                        largest at the bottom.
    width : float, optional
        Default is 1. The width of each character in the plotted logo.
        A value of 1 will mean that there is no gap between each the
        characters at each position. A value of 0 will not draw any
        characters.
    ax : matplotlib.pyplot.Axes or None, optional
        Default is `None`. The axes to plot on. If left as `None`, a new
        axis will be created.
    sequence_type : class, optional
        Default is `selene_sdk.sequences.Genome`. The type of sequence that
        the *in silico* mutagenesis results are associated with. This
        should generally be a subclass of `selene_sdk.sequences.Sequence`.
    font_properties : matplotlib.font_manager.FontProperties or None, optional
        Default is `None`. A `matplotlib.font_manager.FontProperties`
        object that specifies the properties of the font to use for
        plotting the motif. If `None`, no font will be used, and the
        text will be rendered by a path. This method of rendering paths
        is  preferred, as it ensures all character heights correspond to
        the actual values, and that there are no extra gaps between
        the tops and bottoms of characters at each position in the
        sequence logo. If the user opts to use a value other
        than `None`, then no such guarantee can be made.
    color_scheme : list(str) or None, optional
        Default is `None`. A list containing the hex codes or names of
        colors to use, appearing in the order of the bases of the
        sequence type. If left as `None`, a default palette will be made
        with `seaborn.color_palette`, and will have as many
        colors as there are characters in the input sequence alphabet.

    Returns
    -------
    matplotlib.pyplot.Axes
        The axes containing the sequence logo plot.

    Raises
    ------
    ValueError
        If the number of columns in `score_matrix` does not match the
        number of characters in the alphabet of `sequence_type`.

    ValueError
        If the number of colors in `color_palette` does not match the
        number of characters in the alphabet of `sequence_type`.

    Examples
    --------
    We have included an example of the output from a`sequence_logo`
    plot below:

    .. image:: ../../docs/source/_static/img/sequence_logo_example.png

    """
    # Note that everything will break if we do not deepcopy.
    score_matrix = deepcopy(score_matrix)

    score_matrix = score_matrix.transpose()
    if font_properties is not None:
        warnings.warn(
            "Specifying a value for `font_properties` (other than `None`) "
            "will use the `matplotlib`-based character paths, and causes "
            "distortions in the plotted motif. We recommend leaving "
            "`font_properties=None`. See the documentation for details.",
            UserWarning)

    if color_scheme is None:
        color_scheme = sns.color_palette("Set1",
                                         n_colors=len(sequence_type.BASES_ARR))
        color_scheme = color_scheme.as_hex()
    if len(color_scheme) < len(sequence_type.BASES_ARR):
        raise ValueError(
            "Color scheme is shorter than number of bases in sequence.")

    if score_matrix.shape[0] != len(sequence_type.BASES_ARR):
        raise ValueError(
            "Got score with {0} bases for sequence with {1} bases.".format(
                score_matrix.shape[0], len(sequence_type.BASES_ARR)))
    if ax is None:
        _, ax = plt.subplots(figsize=score_matrix.shape)

    # Determine offsets depending on sort order.
    positive_offsets = np.zeros_like(score_matrix)
    negative_offsets = np.zeros_like(score_matrix)
    bases = np.empty(score_matrix.shape, dtype=object)
    bases[:, :] = "?"  # This ensures blanks are visually obvious.

    # Change ordering of things based on input arguments.
    if order == "alpha":
        for i in range(score_matrix.shape[0]):
            bases[i, :] = sequence_type.BASES_ARR[i]

    elif order == "value":
        if np.sum(score_matrix < 0) != 0:
            sorted_scores = np.zeros_like(score_matrix)
            for j in range(score_matrix.shape[1]):
                # Sort the negative values and put them at bottom.
                div = np.sum(score_matrix[:, j] < 0.)
                negative_idx = np.argwhere(score_matrix[:, j] < 0.).flatten()
                negative_sort_idx = np.argsort(score_matrix[negative_idx, j],
                                               axis=None)
                sorted_scores[:div, j] = score_matrix[
                    negative_idx[negative_sort_idx], j]
                bases[:div, j] = sequence_type.BASES_ARR[
                    negative_idx[negative_sort_idx]].flatten()

                # Sort the positive values and stack atop the negatives.
                positive_idx = np.argwhere(score_matrix[:, j] >= 0.).flatten()
                positive_sort_idx = np.argsort(score_matrix[positive_idx, j],
                                               axis=None)
                sorted_scores[div:, j] = score_matrix[
                    positive_idx[positive_sort_idx], j]
                bases[div:, j] = sequence_type.BASES_ARR[
                    positive_idx[positive_sort_idx]].flatten()
            score_matrix = sorted_scores
        else:
            for j in range(score_matrix.shape[1]):
                sort_idx = np.argsort(score_matrix[:, j], axis=None)[::-1]
                bases[:, j] = sequence_type.BASES_ARR[sort_idx]
                score_matrix[:, j] = score_matrix[sort_idx, j]

    # Create offsets for each bar.
    for i in range(score_matrix.shape[0] - 1):
        y_coords = score_matrix[i, :]
        if i > 0:
            negative_offsets[i + 1, :] = negative_offsets[i, :]
            positive_offsets[i + 1, :] = positive_offsets[i, :]
        neg_idx = np.argwhere(y_coords < 0.)
        pos_idx = np.argwhere(y_coords >= 0.)
        negative_offsets[i + 1, neg_idx] += y_coords[neg_idx]
        positive_offsets[i + 1, pos_idx] += y_coords[pos_idx]

    for i in range(score_matrix.shape[0]):
        x_coords = np.arange(score_matrix.shape[1]) + 0.5
        y_coords = score_matrix[i, :]

        # Manage negatives and positives separately.
        offsets = np.zeros(score_matrix.shape[1])
        negative_idx = np.argwhere(y_coords < 0.)
        positive_idx = np.argwhere(y_coords >= 0.)
        offsets[negative_idx] = negative_offsets[i, negative_idx]
        offsets[positive_idx] = positive_offsets[i, positive_idx]
        bars = ax.bar(x_coords,
                      y_coords,
                      color="black",
                      width=width,
                      bottom=offsets)
        for j, bar in enumerate(bars):
            base = bases[i, j]
            bar.set_color(color_scheme[sequence_type.BASE_TO_INDEX[base]])
            bar.set_edgecolor(None)

    # Iterate over the barplot's bars and turn them into letters.
    new_patches = []
    for i, bar in enumerate(ax.patches):
        base_idx = i // score_matrix.shape[1]
        seq_idx = i % score_matrix.shape[1]
        base = bases[base_idx, seq_idx]
        # We construct a text path that tracks the bars in the barplot.
        # Thus, the barplot takes care of scaling and translation,
        #  and we just copy it.
        if font_properties is None:
            text = Path(_SVG_PATHS[base][0], _SVG_PATHS[base][1])
        else:
            text = TextPath((0., 0.), base, fontproperties=font_properties)
        b_x, b_y, b_w, b_h = bar.get_extents().bounds
        t_x, t_y, t_w, t_h = text.get_extents().bounds
        scale = (b_w / t_w, b_h / t_h)
        translation = (b_x - t_x, b_y - t_y)
        text = PathPatch(text, facecolor=bar.get_facecolor(), lw=0.)
        bar.set_facecolor("none")
        text.set_path_effects([_TextPathRenderingEffect(bar)])
        transform = transforms.Affine2D().translate(*translation).scale(*scale)
        text.set_transform(transform)
        new_patches.append(text)

    for patch in new_patches:
        ax.add_patch(patch)
    ax.set_xlim(0, score_matrix.shape[1])
    ax.set_xticks(np.arange(score_matrix.shape[1]) + 0.5)
    ax.set_xticklabels(np.arange(score_matrix.shape[1]))
    return ax
Example #16
0
def cleaned_textpath(text_path):
    """Prepare a matplotlib.textpath.TextPath for intersection checking

    There's a rather nasty little bug hidden in matplotlib's TextPath code
    which causes path intersections to fail.  This works around it by cleaning
    up (and simplifying) the paths.  It is not perfect, as you would see if
    you were to try displaying the resulting paths.

    The basic problem is that vertices associated with a CLOSEPOLY path code
    are supposed to be ignored.  They are in the case of rendering the path
    (which is what made this bug so horrible to track down) but not when
    you are doing other operations, like path intersection or simplifying.
    Since TextPath (for whatever reason) associates gibberish vertices with
    CLOSEPOLY codes, path intersection checks will behave strangely.

    This code splits compound paths into separate paths, and moves the vertex
    for a CLOSEPOLY to the first vertex in the path.

    This eliminates holes in letters such as `e' or `O' but that's a price we
    have to pay.

    Args:
        text_path: A matplotlib.textpath.TextPath

    Returns:
        A list of cleaned up paths.
    """

    paths = list()
    verts = list()
    codes = list()

    for v,c in text_path.iter_segments(curves=False, simplify=False):
        if c == Path.CLOSEPOLY:
            vert = verts[0]
        else:
            vert = v

        if c == Path.MOVETO and len(verts) > 0:
            # We've started a new path.
            newpath = Path(verts, codes)
            newbox = newpath.get_extents()
            
            if len(paths) == 0:
                # If there are no paths we definitely add this one.\
                paths.append(newpath)
            else:
                lastbox = paths[-1].get_extents()
                if bbox_covers(newbox, lastbox):
                    # If this path covers the last one, replace it.
                    paths[-1] = newpath
                elif not bbox_covers(lastbox, newbox):
                    # If the last path doesn't cover this one, throw it out.
                    paths.append(newpath)

            verts = [vert]
            codes = [c]
        else:
            verts.append(vert)
            codes.append(c)

    # Finally, deal with the last path, which may not be explicitly closed.
    if len(verts) > 0:
        newpath = Path(verts, codes)
        newbox = newpath.get_extents()
        if len(paths) == 0:
            paths.append(newpath)
        else:
            lastbox = paths[-1].get_extents()
            if bbox_covers(newbox, lastbox):
                paths[-1] = newpath
            elif not bbox_covers(lastbox, newbox):
                paths.append(newpath)
    
    return paths
Example #17
0
for (vertex, code) in path.iter_segments(simplify = True):
    vertices.append(vertex.tolist())
    codes.append(code)

# <codecell>

cleanpath = Path(vertices, codes)
len(cleanpath)

# <codecell>

codes[-1] = Path.CLOSEPOLY

# <codecell>

bbox = cleanpath.get_extents()
print bbox

# <codecell>

bbox.bounds

# <codecell>

hemi_masked = path.contains_points( hemi_kp )
hemi_kp_masked = hemi_kp[ np.where(hemi_masked) ]

# <codecell>

fig, axs = plt.subplots(1, 2, figsize = (15, 15))