def _view_poi_histogram(self, event): current_cluster = self.current_cluster() if not current_cluster.points_of_interest: plt.figure() plt.figtext(0.1, 0.1, 'Sorry, no points of interest for this cluster. Try running explorer again with -poi poi_dataset.bed') plt.show() return # Pandas tend to crash if subplots is True when only one dimension number_poi_collections = len(current_cluster.points_of_interest_histogram.columns) axes = current_cluster.points_of_interest_histogram.plot(kind='bar', subplots=(number_poi_collections > 1)) if number_poi_collections == 1: axes = [axes] for ax in axes: ax.set_ylabel('Number of regions') plt.xlabel('Bin') plt.suptitle('Original points of interest') axes = current_cluster.tracked_points_histogram.plot(kind='bar', subplots=(number_poi_collections > 1)) if number_poi_collections == 1: axes = [axes] for ax in axes: ax.set_ylabel('Number of regions') plt.xlabel('Warped bin') plt.suptitle('Warped points of interest') plt.show()
def create_figure(self, figsize=(12, 10), interactive=True): plt.figure(num=None, figsize=figsize, facecolor='w', edgecolor='k') self._gs_main = gridspec.GridSpec(2, 2, wspace=0, height_ratios=[1, 15]) self._figure = plt.gcf() self._ax_dendrogram = plt.subplot(self.gs_dendrogram, rasterized=True) if interactive: self._figure.canvas.mpl_connect('button_press_event', self._onclick_listener) self.draw_buttons()
def _plot_item_in_figure(self, index): data = self.current_cluster().data.ix[index] projected_data = self.current_cluster().projected_data.ix[index] prototype = self.current_cluster().prototype poi = self.current_cluster().points_of_interest.get(index, {}) tracked_poi = self.current_cluster().tracked_points_of_interest.get(index, {}) plt.figure() ax1 = plt.subplot(3, 1, 1) data.plot(ax=ax1, legend=False) plt.figlegend(*ax1.get_legend_handles_labels(), loc='lower center') if poi: lim_min, lim_max = ax1.get_ylim() height = (lim_max - lim_min) / 20 points_plotted_on = defaultdict(lambda: 0) for key, value in poi.iteritems(): colour = self.highlight_colours[key] for point in value: items_on_current_point = points_plotted_on[point] ax1.add_patch(Rectangle((point, lim_min + (height*items_on_current_point)), width=1, height=height, facecolor=colour, edgecolor='k')) points_plotted_on[point] += 1 plt.title('Original') ax2 = plt.subplot(3, 1, 2, sharey=ax1) prototype.plot(ax=ax2, legend=False) plt.title('Cluster Prototype') ax3 = plt.subplot(3, 1, 3, sharey=ax1) projected_data.plot(ax=ax3, legend=False) if tracked_poi: lim_min, lim_max = ax3.get_ylim() height = (lim_max - lim_min) / 20 points_plotted_on = defaultdict(lambda: 0) for key, value in tracked_poi.iteritems(): colour = self.highlight_colours[key] for point in value: items_on_current_point = points_plotted_on[point] ax3.add_patch(Rectangle((point, lim_min + (height*items_on_current_point)), width=1, height=height, facecolor=colour, edgecolor='k')) points_plotted_on[point] += 1 plt.title('Warped') plt.suptitle(index) figure_dtw_mappings = visualise_dtw_mappings(data, prototype, dtw_function=self.dtw_function, columns=data.columns, sequence_x_label=index, sequence_y_label='Cluster Prototype')
def prototype_images_from_node_list(node_list, output_directory): print '> Saving images to {0!r}'.format(output_directory) ndims = node_list[0].prototype.shape[1] plt.figure(figsize=(3 * ndims, 2)) for node in node_list: filename = '{0}.png'.format(node.id) full_filename = os.path.join(output_directory, filename) print '> Saving {0}'.format(full_filename) prototype_T = node.prototype.values.T for i in xrange(ndims): plt.subplot(1, ndims, i + 1) plt.plot(prototype_T[i]) plt.savefig(full_filename) plt.clf()
def prototype_images_from_node_list(node_list, output_directory): print '> Saving images to {0!r}'.format(output_directory) ndims = node_list[0].prototype.shape[1] plt.figure(figsize=(3 * ndims, 2)) for node in node_list: filename = '{0}.png'.format(node.id) full_filename = os.path.join(output_directory, filename) print '> Saving {0}'.format(full_filename) prototype_T = node.prototype.values.T for i in xrange(ndims): plt.subplot(1, ndims, i+1) plt.plot(prototype_T[i]) plt.savefig(full_filename) plt.clf()
def _plot_regular_heatmap_on_figure(self, cluster): f = plt.figure(figsize=(11.7, 8.3)) plt.subplots_adjust(left=0.05, bottom=0.05, top=0.95, right=0.95) self._enlarged_heatmap_axis = plt.gca() cluster.data.plot_heatmap(horizontal_grid=True, sort_by=None, highlighted_points=cluster.points_of_interest, highlight_colours=self.highlight_colours) f.canvas.mpl_connect('button_press_event', self._onclick_listener) return f
def create_figure(self, figsize=(12, 10), interactive=True): self._figure = plt.figure(num=None, figsize=figsize, facecolor='w', edgecolor='k') self.title = plt.suptitle("") # Create text object for title if interactive: self.create_buttons() self._figure.canvas.mpl_connect('button_press_event', self._onclick_listener) self.draw()
def plot_dtw_sequences_dist_cost_and_path(sequence_x, sequence_y, dist, cost_matrix, path): """ Generates a full DTW plot with both the cost matrix, path and both of the sequences :param sequence_x: :param sequence_y: :param dist: :param cost_matrix: :param path: :return: """ sequence_x = np.asarray(sequence_x) sequence_y = np.asarray(sequence_y) # Based on: http://matplotlib.org/examples/pylab_examples/scatter_hist.html figure = plt.figure() null_fmt = NullFormatter() # no labels # definitions for the axes left, width = 0.1, 0.65 bottom, height = 0.1, 0.65 ax_width = 0.2 bottom_h = left_h = left + width + 0.02 rect_cost = [left, bottom, width, height] rect_sequence_x = [left, bottom_h, width, ax_width] rect_sequence_y = [left_h, bottom, ax_width, height] text_pos_x = left_h text_pos_y = bottom_h ax_cost = plt.axes(rect_cost) ax_sequence_x = plt.axes(rect_sequence_x) ax_sequence_y = plt.axes(rect_sequence_y) # Drop labels ax_sequence_x.xaxis.set_major_formatter(null_fmt) ax_sequence_y.yaxis.set_major_formatter(null_fmt) # Plot main plot plot_dtw_cost_and_path(cost_matrix, path, ax=ax_cost) ax_sequence_x.plot(range(len(sequence_x)), sequence_x) ax_sequence_y.plot(sequence_y, range(len(sequence_y))) # Set limits based on cost ax_sequence_x.set_xlim(ax_cost.get_xlim()) ax_sequence_y.set_ylim(ax_cost.get_ylim()) # Set Limits based on seq ax_sequence_x.set_ylim( min(sequence_x.min(), sequence_y.min()) - 1, max(sequence_x.max(), sequence_y.max()) + 1) ax_sequence_y.set_xlim( min(sequence_x.min(), sequence_y.min()) - 1, max(sequence_x.max(), sequence_y.max()) + 1) # Add test showing the value of dist plt.figtext(text_pos_x, text_pos_y, 'Distance:\n{0:.5f}'.format(dist), size='medium') return figure
def visualise_dtw_mappings(sequence_x, sequence_y, dtw_function=dtw_std, columns=None, title=None, sequence_x_label=None, sequence_y_label=None): def major_tick_step(ax, axis): if axis == 'x': ticks = ax.get_xticks() else: ticks = ax.get_yticks() try: step = ticks[1] - ticks[0] except IndexError: step = 0.2 return step def expand_axes(ax): x_increment = major_tick_step(ax, 'x') / 8.0 min_x, max_x = ax.get_xlim() ax.set_xlim(min_x - x_increment, max_x + x_increment) y_increment = major_tick_step(ax, 'y') / 8.0 min_y, max_y = ax.get_ylim() ax.set_ylim(min_y - y_increment, max_y + y_increment) def add_reversed_annotation(ax): min_x, max_x = ax.get_xlim() min_y, max_y = ax.get_ylim() offset_x = major_tick_step(ax, 'x') offset_y = major_tick_step(ax, 'y') ax.text(min_x + offset_x / 8, max_y - offset_y / 2 - offset_y / 8, '(reversed)') dist, cost, path = dtw_function(sequence_x, sequence_y, dist_only=False) sequence_x = np.asarray(sequence_x) sequence_y = np.asarray(sequence_y) try: ndim = sequence_x.shape[1] except IndexError: ndim = 1 reversed = dtw_path_is_reversed(path) if reversed: sequence_x = reverse_sequence(sequence_x) path_x = np.max(path[0]) - path[0] path_y = path[1] path = (path_x, path_y) sequence_y_T = np.atleast_2d(sequence_y.T) sequence_x_T = np.atleast_2d(sequence_x.T) if columns is None and ndim > 1: columns = ['Dimension #{0}'.format(i) for i in range(1, ndim + 1)] elif ndim > 1: if len(columns) != ndim: raise ValueError( 'Number of column titles does not match the number of dimensions' ) main_y_axis = None xaxes_regular = [None] * ndim xaxes_warped = [None] * ndim figure = plt.figure() figure.subplots_adjust(wspace=0.01, hspace=0.1) for i in range(ndim): x = sequence_x_T[i] print x.shape y = sequence_y_T[i] ax2 = plt.subplot(2, ndim, ndim + i + 1, sharey=main_y_axis, sharex=xaxes_warped[i]) ax2.plot(y, color='g') if i > 0: ax2.yaxis.set_visible(False) expand_axes(ax2) if not main_y_axis: main_y_axis = ax2 if not xaxes_warped[i]: xaxes_warped[i] = ax2 ax1 = plt.subplot(2, ndim, i + 1, sharey=main_y_axis, sharex=xaxes_regular[i]) ax1.plot(x, color='b') expand_axes(ax1) if ndim > 1: ax1.set_title(columns[i]) if i > 0: ax1.yaxis.set_visible(False) if not xaxes_regular[i]: xaxes_regular[i] = ax1 if reversed: add_reversed_annotation(ax1) for p_i, p_j in zip(path[0], path[1]): xy_a = (p_i, x[p_i]) xy_b = (p_j, y[p_j]) con = ConnectionPatch(xyA=xy_a, xyB=xy_b, coordsA="data", coordsB="data", axesA=ax1, axesB=ax2, arrowstyle="-", shrinkB=2, shrinkA=2, alpha=0.2) ax1.add_artist(con) if title is not None: plt.suptitle(title) lines = xaxes_regular[0].get_lines() lines.extend(xaxes_warped[0].get_lines()) if sequence_x_label and sequence_y_label: plt.figlegend(lines, (sequence_x_label, sequence_y_label), 'lower center') return figure
def plot_dtw_sequences_dist_cost_and_path(sequence_x, sequence_y, dist, cost_matrix, path): """ Generates a full DTW plot with both the cost matrix, path and both of the sequences :param sequence_x: :param sequence_y: :param dist: :param cost_matrix: :param path: :return: """ sequence_x = np.asarray(sequence_x) sequence_y = np.asarray(sequence_y) # Based on: http://matplotlib.org/examples/pylab_examples/scatter_hist.html figure = plt.figure() null_fmt = NullFormatter() # no labels # definitions for the axes left, width = 0.1, 0.65 bottom, height = 0.1, 0.65 ax_width = 0.2 bottom_h = left_h = left + width + 0.02 rect_cost = [left, bottom, width, height] rect_sequence_x = [left, bottom_h, width, ax_width] rect_sequence_y = [left_h, bottom, ax_width, height] text_pos_x = left_h text_pos_y = bottom_h ax_cost = plt.axes(rect_cost) ax_sequence_x = plt.axes(rect_sequence_x) ax_sequence_y = plt.axes(rect_sequence_y) # Drop labels ax_sequence_x.xaxis.set_major_formatter(null_fmt) ax_sequence_y.yaxis.set_major_formatter(null_fmt) # Plot main plot plot_dtw_cost_and_path(cost_matrix, path, ax=ax_cost) ax_sequence_x.plot(range(len(sequence_x)), sequence_x) ax_sequence_y.plot(sequence_y, range(len(sequence_y))) # Set limits based on cost ax_sequence_x.set_xlim(ax_cost.get_xlim()) ax_sequence_y.set_ylim(ax_cost.get_ylim()) # Set Limits based on seq ax_sequence_x.set_ylim(min(sequence_x.min(), sequence_y.min()) - 1, max(sequence_x.max(), sequence_y.max()) + 1) ax_sequence_y.set_xlim(min(sequence_x.min(), sequence_y.min()) - 1, max(sequence_x.max(), sequence_y.max()) + 1) # Add test showing the value of dist plt.figtext(text_pos_x, text_pos_y, 'Distance:\n{0:.5f}'.format(dist), size='medium') return figure
def visualise_dtw_mappings(sequence_x, sequence_y, dtw_function=dtw_std, columns=None, title=None, sequence_x_label=None, sequence_y_label=None): def major_tick_step(ax, axis): if axis == 'x': ticks = ax.get_xticks() else: ticks = ax.get_yticks() try: step = ticks[1] - ticks[0] except IndexError: step = 0.2 return step def expand_axes(ax): x_increment = major_tick_step(ax, 'x') / 8.0 min_x, max_x = ax.get_xlim() ax.set_xlim(min_x - x_increment, max_x + x_increment) y_increment = major_tick_step(ax, 'y') / 8.0 min_y, max_y = ax.get_ylim() ax.set_ylim(min_y - y_increment, max_y + y_increment) def add_reversed_annotation(ax): min_x, max_x = ax.get_xlim() min_y, max_y = ax.get_ylim() offset_x = major_tick_step(ax, 'x') offset_y = major_tick_step(ax, 'y') ax.text(min_x + offset_x / 8, max_y - offset_y / 2 - offset_y / 8, '(reversed)') dist, cost, path = dtw_function(sequence_x, sequence_y, dist_only=False) sequence_x = np.asarray(sequence_x) sequence_y = np.asarray(sequence_y) try: ndim = sequence_x.shape[1] except IndexError: ndim = 1 reversed = dtw_path_is_reversed(path) if reversed: sequence_x = reverse_sequence(sequence_x) path_x = np.max(path[0]) - path[0] path_y = path[1] path = (path_x, path_y) sequence_y_T = np.atleast_2d(sequence_y.T) sequence_x_T = np.atleast_2d(sequence_x.T) if columns is None and ndim > 1: columns = ['Dimension #{0}'.format(i) for i in range(1, ndim+1)] elif ndim > 1: if len(columns) != ndim: raise ValueError('Number of column titles does not match the number of dimensions') main_y_axis = None xaxes_regular = [None] * ndim xaxes_warped = [None] * ndim figure = plt.figure() figure.subplots_adjust(wspace=0.01, hspace=0.1) for i in range(ndim): x = sequence_x_T[i] print x.shape y = sequence_y_T[i] ax2 = plt.subplot(2, ndim, ndim + i + 1, sharey=main_y_axis, sharex=xaxes_warped[i]) ax2.plot(y, color='g') if i > 0: ax2.yaxis.set_visible(False) expand_axes(ax2) if not main_y_axis: main_y_axis = ax2 if not xaxes_warped[i]: xaxes_warped[i] = ax2 ax1 = plt.subplot(2, ndim, i + 1, sharey=main_y_axis, sharex=xaxes_regular[i]) ax1.plot(x, color='b') expand_axes(ax1) if ndim > 1: ax1.set_title(columns[i]) if i > 0: ax1.yaxis.set_visible(False) if not xaxes_regular[i]: xaxes_regular[i] = ax1 if reversed: add_reversed_annotation(ax1) for p_i, p_j in zip(path[0], path[1]): xy_a = (p_i, x[p_i]) xy_b = (p_j, y[p_j]) con = ConnectionPatch(xyA=xy_a, xyB=xy_b, coordsA="data", coordsB="data", axesA=ax1, axesB=ax2, arrowstyle="-", shrinkB=2, shrinkA=2, alpha=0.2) ax1.add_artist(con) if title is not None: plt.suptitle(title) lines = xaxes_regular[0].get_lines() lines.extend(xaxes_warped[0].get_lines()) if sequence_x_label and sequence_y_label: plt.figlegend(lines, (sequence_x_label, sequence_y_label), 'lower center') return figure
def _plot_prototype_on_figure(self, cluster): f = plt.figure() plt.subplots_adjust(left=0.05, bottom=0.05, top=0.95, right=0.95) cluster.prototype.plot(ax=f.gca()) return f