def fill_gradient(self, canvas, X, percentiles, color=Tango.colorsHex['mediumBlue'], label=None, **kwargs): ax = canvas plots = [] if 'edgecolors' not in kwargs: kwargs['edgecolors'] = 'none' if 'facecolors' in kwargs: color = kwargs.pop('facecolors') if 'array' in kwargs: array = kwargs.pop('array') else: array = 1. - np.abs(np.linspace(-.97, .97, len(percentiles) - 1)) if 'alpha' in kwargs: alpha = kwargs.pop('alpha') else: alpha = .8 if 'cmap' in kwargs: cmap = kwargs.pop('cmap') else: cmap = LinearSegmentedColormap.from_list('WhToColor', (color, color), N=array.size) cmap._init() cmap._lut[:-3, -1] = alpha * array kwargs['facecolors'] = [cmap(i) for i in np.linspace(0, 1, cmap.N)] # pop where from kwargs where = kwargs.pop('where') if 'where' in kwargs else None # pop interpolate, which we actually do not do here! if 'interpolate' in kwargs: kwargs.pop('interpolate') def pairwise(iterable): "s -> (s0,s1), (s1,s2), (s2, s3), ..." from itertools import tee #try: # from itertools import izip as zip #except ImportError: # pass a, b = tee(iterable) next(b, None) return list(zip(a, b)) polycol = [] for y1, y2 in pairwise(percentiles): import matplotlib.mlab as mlab # Handle united data, such as dates ax._process_unit_info(xdata=X, ydata=y1) ax._process_unit_info(ydata=y2) # Convert the arrays so we can work with them from numpy import ma x = ma.masked_invalid(ax.convert_xunits(X)) y1 = ma.masked_invalid(ax.convert_yunits(y1)) y2 = ma.masked_invalid(ax.convert_yunits(y2)) if y1.ndim == 0: y1 = np.ones_like(x) * y1 if y2.ndim == 0: y2 = np.ones_like(x) * y2 if where is None: where = np.ones(len(x), np.bool) else: where = np.asarray(where, np.bool) if not (x.shape == y1.shape == y2.shape == where.shape): raise ValueError("Argument dimensions are incompatible") from functools import reduce mask = reduce(ma.mask_or, [ma.getmask(a) for a in (x, y1, y2)]) if mask is not ma.nomask: where &= ~mask polys = [] for ind0, ind1 in mlab.contiguous_regions(where): xslice = x[ind0:ind1] y1slice = y1[ind0:ind1] y2slice = y2[ind0:ind1] if not len(xslice): continue N = len(xslice) p = np.zeros((2 * N + 2, 2), np.float) # the purpose of the next two lines is for when y2 is a # scalar like 0 and we want the fill to go all the way # down to 0 even if none of the y1 sample points do start = xslice[0], y2slice[0] end = xslice[-1], y2slice[-1] p[0] = start p[N + 1] = end p[1:N + 1, 0] = xslice p[1:N + 1, 1] = y1slice p[N + 2:, 0] = xslice[::-1] p[N + 2:, 1] = y2slice[::-1] polys.append(p) polycol.extend(polys) from matplotlib.collections import PolyCollection if 'zorder' not in kwargs: kwargs['zorder'] = 0 plots.append(PolyCollection(polycol, **kwargs)) ax.add_collection(plots[-1], autolim=True) ax.autoscale_view() return plots
def export_tissue_cuts(self, phase: SimPhase, conf: SimConfExportPlotCells) -> None: ''' Plot a **tissue and cut profile tessellation** (i.e., tiled mosaic of all cells spatially subdivided into tissue and cut profile regions such that all cells in the same region share the same arbitrary color) for the cell cluster. This plot is irrespective of time step. ''' # Prepare to export the current plot. self._export_prep(phase) # Localize frequently accessed fields for convenience. p = phase.p dyna = phase.dyna cells = phase.cells colormap = phase.p.background_cm col_dic = {} cb_ticks = [] cb_tick_labels = [] # Ordered dictionary mapping from the name of each tissue and cut # profile to a one-dimensional Numpy array of the 0-based indices of # all cells owned by this profile. # # Note that order is absolutely significant. The first tissue profile # is a pseudo-tissue defining the cell cluster itself. If order were # *NOT* preserved here, this tissue would be assigned an arbitrary # z-order, in which case all tissues assigned smaller z-orders would be # entirely obscured by that pseudo-tissue covering the cell cluster. profile_name_to_cells_index = OrderedDict() fig = pyplot.figure() ax = pyplot.subplot(111) # For the name and object encapsulating each tissue profile... for tissue_name, _ in dyna.tissue_name_to_profile.items(): # One-dimensional Numpy array of the indices of all tissue cells. tissue_cells_index = dyna.cell_target_inds[tissue_name] # If this tissue contains no cells, skip to the next tissue. if not len(tissue_cells_index): logs.log_warning('Tissue "%s" contains no cells.', tissue_name) continue # Else, tissue contains one or more cells. Map this tissue to these # indices (for subsequent lookup). profile_name_to_cells_index[tissue_name] = tissue_cells_index #FIXME: The "p.plot_cutlines" boolean is only ever leveraged here and #thus is arguably extraneous. Consider refactoring as follows: # #* Remove the "p.plot_cutlines" boolean and corresponding # YAML-formetted default configuration option. #* Split the existing "tissue_cuts" plot type in the "cell cluster # pipeline" into the following two types: # * "tissue", unconditionally plotting *ONLY* tissue profiles. # * "tissue_cuts", unconditionally plotting both tissue and cut # profiles. #* Define a new private _export_profiles() method as follows: # @type_check # _export_profiles( # self, # conf: SimConfExportPlotCells, # is_tissue: bool, # is_cuts: bool # ) -> None: #* Implement export_tissue() to call _export_profiles() as: # self._export_profiles( # self, # conf=conf, # is_tissue=True, # is_cuts=False, # ) #* Implement export_tissue_cuts() similarly. # If plotting cut profiles as well *AND* the cutting event is # enabled... if p.plot_cutlines and dyna.event_cut is not None: # For the name and object encapsulating each cut profile... for cut_name, cut_profile in dyna.cut_name_to_profile.items(): # Map this cut to the indices of all cells cut by this profile. profile_name_to_cells_index[cut_name] = ( cut_profile.picker.pick_cells(cells=cells, p=p)) # Minimum and maximum 0-based integers uniquely identifying the first # and last tissue and cut profile (respoctively), localized for # ordering purposes in the colorbar legend. profile_zorder = 0 profile_zorder_max = len(profile_name_to_cells_index) # For the name and one-dimensional Numpy array of the 0-based indices # of all cells in each tissue and/or cut profile... for profile_name, profile_cells_index in ( profile_name_to_cells_index.items()): # logs.log_debug('Plotting tissue "%s"...', profile_name) profile_zorder += 1 profile_points = mathunit.upscale_coordinates( cells.cell_verts[profile_cells_index]) z = np.zeros(len(profile_points)) z[:] = profile_zorder col_dic[profile_name] = PolyCollection(profile_points, array=z, cmap=colormap, edgecolors='none') col_dic[profile_name].set_clim(0, profile_zorder_max) # col_dic[profile_name].set_alpha(0.8) col_dic[profile_name].set_zorder(profile_zorder) ax.add_collection(col_dic[profile_name]) # Add this profile name to the colour legend. cb_ticks.append(profile_zorder) cb_tick_labels.append(profile_name) # logs.log_debug('Plotting colorbar ticks: %r', cb_ticks) # logs.log_debug('Plotting colorbar tick labels: %r', cb_tick_labels) ax_cb = None if dyna.tissue_name_to_profile: # Name of the first tissue profile. tissue_first_name = iterget.get_item_first( dyna.tissue_name_to_profile.keys()) # Color mappable associated with this tissue profile, guaranteed in # this case to be a "PolyCollection" instance. tissue_first_mappable = col_dic[tissue_first_name] ax_cb = fig.colorbar(tissue_first_mappable, ax=ax, ticks=cb_ticks) ax_cb.ax.set_yticklabels(cb_tick_labels) if p.visual.is_show_cell_indices: for i, cll in enumerate(cells.cell_centres): ax.text(p.um * cll[0], p.um * cll[1], i, ha='center', va='center', zorder=20) ax.set_xlabel('Spatial Distance [um]') ax.set_ylabel('Spatial Distance [um]') ax.set_title('Cell Cluster') ax.axis('equal') ax.axis(phase.cache.upscaled.extent) # Export this plot to disk and/or display. self._export(phase=phase, basename='cluster_mosaic')
V = np.zeros((8, 2, 3, 2)) for i in range(4): theta = np.pi / 4 + i * np.pi / 2 c, s = np.cos(theta), np.sin(theta) Z = np.array([[c, s], [-s, c]]) V[i, 0] = [(0, 0), (-1, 1), (0, 5)] @ Z.T V[i, 1] = [(0, 0), (+1, 1), (0, 5)] @ Z.T theta -= np.pi / 4 c, s = np.cos(theta), np.sin(theta) Z = np.array([[c, s], [-s, c]]) V[4 + i, 0] = [(0, 0), (-1, 1), (0, 5)] @ Z.T V[4 + i, 1] = [(0, 0), (+1, 1), (0, 5)] @ Z.T V = V.reshape(16, 3, 2) V = 0.9 * V / 5 + (9, 1) FC = np.zeros((16, 4)) FC[0::2] = 0, 0, 0, 1 FC[1::2] = 1, 1, 1, 1 collection = PolyCollection(V, edgecolors="black", facecolors=FC, lw=0.75, zorder=20) ax.add_collection(collection) # Done ax.set_xlim(-1, 11), ax.set_xticks([]) ax.set_ylim(-1, 11), ax.set_yticks([]) plt.tight_layout() # plt.savefig("dyson-hatching.pdf") plt.show()
fig = plt.figure() ax1 = fig.add_subplot(111, projection='polar') # generating some data: C = np.random.rand(30) * 15 + 40 h = np.random.rand(30) * 15 + 290 h = np.radians(h) # convert values of the angle from degrees to radians # following scipy example points = np.array([p for p in zip(h, C)]) hull = ConvexHull(points) for i in [points[hull.vertices, :]]: print(i) ax1.scatter(h, C, s=5, marker='o', color='b') # adding the convex hull to ax1 as a PolyCollection: ax1.add_collection( PolyCollection( [points[hull.vertices, :]], edgecolors='r', facecolors='w', linewidths=2, zorder=-1, )) ax1.set_rmax(60) plt.show()
def plot_3d_polygons(self, **kwargs): """ :return: """ figure = kwargs.get('figure', None) axs = kwargs.get('axs', None) title = kwargs.get('title', ' ') kind = kwargs.get('kind', 'Spectrum') alpha = kwargs.get('alpha', 0.5) if figure is None: fig = plt.figure() else: fig = figure fig.clf() if axs is None: ax = fig.add_subplot(111, projection='3d') else: ax = axs def cc(arg): return colorConverter.to_rgba(arg, alpha=0.6) #col_options = [cc('r'), cc('g'), cc('b'), cc('y')] verts = [] colors = [] zs = [] wl_range = [3000, 0] cnt_range = [0, 10] for data in self.measurements: if data.__kind__ == kind: sig = data.bin_data() #print sig if len(sig): zs.append(data.ex_wl) if min(sig[:, 1]) != 0: sig[:, 1] = sig[:, 1] - min(sig[:, 1]) sig[-1, 1] = sig[0, 1] = 0 verts.append(sig) colors.append(data.color) wl_range = [ min(wl_range[0], min(sig[:, 0])), max(wl_range[1], max(sig[:, 0])) ] cnt_range = [ min(cnt_range[0], min(sig[:, 1])), max(cnt_range[1], max(sig[:, 1])) ] poly = PolyCollection(verts, closed=False, facecolors=colors) # poly.set_alpha(alpha) ax.add_collection3d(poly, zs=zs, zdir='y') ax.set_xlabel('Emission [nm]') ax.set_xlim3d(wl_range) ax.set_ylabel('Excitation [nm]') ax.set_ylim3d(min(zs) - 10, max(zs) + 10) ax.set_zlabel('Counts') ax.set_zlim3d(cnt_range) plt.title(title) plt.show()
fig = plt.figure() ax = fig.gca(projection='3d') a, b = -3, 3 gs = 100 xs = np.linspace(a, b, gs) # == Build verts == # greys = np.linspace(0.3, 0.7, nmax) verts = [] for n in ns: density = gaussian_kde(Y[:, n - 1]) ys = density(xs) verts.append(list(zip(xs, ys))) poly = PolyCollection(verts, facecolors=[str(g) for g in greys]) poly.set_alpha(0.85) ax.add_collection3d(poly, zs=ns, zdir='x') # ax.text(np.mean(rhos), a-1.4, -0.02, r'$\beta$', fontsize=16) # ax.text(np.max(rhos)+0.016, (a+b)/2, -0.02, r'$\log(y)$', fontsize=16) ax.set_xlim3d(1, nmax) ax.set_xticks(ns) ax.set_xlabel("n") ax.set_yticks((-3, 0, 3)) ax.set_ylim3d(a, b) ax.set_zlim3d(0, 0.4) ax.set_zticks((0.2, 0.4)) plt.show()
def mmd_tsne_plot_DC(dc, mmd_fn=None, condition_fn=None, mmd=None, \ conditions=None, perplexity=30.0, s=4.0, alpha=0.8, label_func=None, \ ax=None, save_and_close=True, filename='mmd_tsne.pdf', load_data=False): """ Compute and plot a t-SNE layout from an MMD matrix. Either pass ``mmd`` and ``conditions`` directly, or specify ``mmd_fn`` and ``condition_fn`` and set ``load_data=True``. TO DO: ----- * add option to calculate MMD. Parameters ---------- dc : ava.data.data_container.DataContainer DataContainer object. mmd_fn : str Where MMD values are saved to/loaded from. condition_fn : str Where conditions are saved to/loaded from. mmd : {numpy.ndarray, None}, optional MMD matrix. Defaults to ``None``. conditions : {numpy.ndarray, None}, optional Condition for each entry of the MMD array. Defaults to ``None``. perplexity : float, optional Passed to t-SNE. Defaults to ``30.0``. s : float, optional Passed to ``matplotlib.pyplot.scatter``. Defaults to ``4.0``. alpha : float, optional Passed to ``matplotlib.pyplot.scatter``. Defaults to ``0.8``. label_func : {function, None}, optional Maps a conditions to a label (string) for annotating points. Defaults to ``None``. ax : matplotlib.axes._subplots.AxesSubplot, optional Matplotlib axis. Defaults to the current axis, ``plt.gca()``. save_and_close : bool, optional Save and close the figure. Defaults to ``True``. filename : str, optional Where to save plot. Defaults to ``'mmd_tsne.pdf'``. load_data : bool, optional Whether to load the MMD and condition data from ``mmd_fn`` and ``condition_fn``. Defaults to ``False``. """ if load_data: assert mmd_fn is not None and condition_fn is not None try: mmd = np.load(mmd_fn) conditions = np.load(condition_fn) except: print("Unable to load data!") return else: assert mmd is not None and conditions is not None mmd = np.clip(mmd, 0, None) all_conditions = list(np.unique(conditions)) # np.unique sorts things colors = [COLOR_LIST[i % len(COLOR_LIST)] for i in conditions] all_colors = [COLOR_LIST[i % len(COLOR_LIST)] for i in all_conditions] transform = TSNE(n_components=2, random_state=42, metric='precomputed', \ method='exact', perplexity=perplexity) embed = transform.fit_transform(mmd) if ax is None: ax = plt.gca() poly_colors = [] poly_vals = [] for i in range(len(conditions) - 1): for j in range(i + 1, len(conditions)): if conditions[i] == conditions[j]: color = to_rgba(colors[i], alpha=0.7) ax.plot([embed[i,0],embed[j,0]], [embed[i,1],embed[j,1]], \ c=color, lw=0.5) for k in range(j + 1, len(conditions)): if conditions[k] == conditions[j]: arr = np.stack([embed[i], embed[j], embed[k]]) poly_colors.append(to_rgba(colors[i], alpha=0.2)) poly_vals.append(arr) pc = PolyCollection(poly_vals, color=poly_colors) ax.add_collection(pc) ax.scatter(embed[:, 0], embed[:, 1], color=colors, s=s, alpha=alpha) if label_func is not None: for i in range(len(embed)): ax.annotate(label_func(conditions[i]), embed[i]) plt.axis('off') if save_and_close: plt.savefig(os.path.join(dc.plots_dir, filename)) plt.close('all')
def tile(self, x, y, w, h, color=None, anchor='center', edgecolors='face', linewidth=0.8, **kwargs): """Plot rectanguler tiles based onto these `Axes`. ``x`` and ``y`` give the anchor point for each tile, with ``w`` and ``h`` giving the extent in the X and Y axis respectively. Parameters ---------- x, y, w, h : `array_like`, shape (n, ) Input data color : `array_like`, shape (n, ) Array of amplitudes for tile color anchor : `str`, optional Anchor point for tiles relative to ``(x, y)`` coordinates, one of - ``'center'`` - center tile on ``(x, y)`` - ``'ll'`` - ``(x, y)`` defines lower-left corner of tile - ``'lr'`` - ``(x, y)`` defines lower-right corner of tile - ``'ul'`` - ``(x, y)`` defines upper-left corner of tile - ``'ur'`` - ``(x, y)`` defines upper-right corner of tile **kwargs Other keywords are passed to :meth:`~matplotlib.collections.PolyCollection` Returns ------- collection : `~matplotlib.collections.PolyCollection` the collection of tiles drawn Examples -------- >>> import numpy >>> from matplotlib import pyplot >>> import gwpy.plot # to get gwpy's Axes >>> x = numpy.arange(10) >>> y = numpy.arange(x.size) >>> w = numpy.ones_like(x) * .8 >>> h = numpy.ones_like(x) * .8 >>> fig = pyplot.figure() >>> ax = fig.gca() >>> ax.tile(x, y, w, h, anchor='ll') >>> pyplot.show() """ # get color and sort if color is not None and kwargs.get('c_sort', True): sortidx = color.argsort() x = x[sortidx] y = y[sortidx] w = w[sortidx] h = h[sortidx] color = color[sortidx] # define how to make a polygon for each tile if anchor == 'll': def _poly(x, y, w, h): return ((x, y), (x, y + h), (x + w, y + h), (x + w, y)) elif anchor == 'lr': def _poly(x, y, w, h): return ((x - w, y), (x - w, y + h), (x, y + h), (x, y)) elif anchor == 'ul': def _poly(x, y, w, h): return ((x, y - h), (x, y), (x + w, y), (x + w, y - h)) elif anchor == 'ur': def _poly(x, y, w, h): return ((x - w, y - h), (x - w, y), (x, y), (x, y - h)) elif anchor == 'center': def _poly(x, y, w, h): return ((x - w / 2., y - h / 2.), (x - w / 2., y + h / 2.), (x + w / 2., y + h / 2.), (x + w / 2., y - h / 2.)) else: raise ValueError("Unrecognised tile anchor {!r}".format(anchor)) # build collection cmap = kwargs.pop('cmap', rcParams['image.cmap']) coll = PolyCollection((_poly(*tile) for tile in zip(x, y, w, h)), edgecolors=edgecolors, linewidth=linewidth, **kwargs) if color is not None: coll.set_array(color) coll.set_cmap(cmap) out = self.add_collection(coll) self.autoscale_view() return out
def index_bar( ax, vals, facecolor='b', edgecolor='l', width=4, alpha=1.0, ): """Add a bar collection graph with height vals (-1 is missing). Parameters ---------- ax : `Axes` an Axes instance to plot to vals : sequence a sequence of values facecolor : color the color of the bar face edgecolor : color the color of the bar edges width : int the bar width in points alpha : float bar transparency Returns ------- ret : `barCollection` The `barrCollection` added to the axes """ facecolors = (colorConverter.to_rgba(facecolor, alpha), ) edgecolors = (colorConverter.to_rgba(edgecolor, alpha), ) right = width / 2.0 left = -width / 2.0 bars = [((left, 0), (left, v), (right, v), (right, 0)) for v in vals if v != -1] sx = ax.figure.dpi * (1.0 / 72.0) # scale for points sy = ax.bbox.height / ax.viewLim.height barTransform = Affine2D().scale(sx, sy) offsetsBars = [(i, 0) for i, v in enumerate(vals) if v != -1] barCollection = PolyCollection( bars, facecolors=facecolors, edgecolors=edgecolors, antialiaseds=(0, ), linewidths=(0.5, ), offsets=offsetsBars, transOffset=ax.transData, ) barCollection.set_transform(barTransform) minpy, maxx = (0, len(offsetsBars)) miny = 0 maxy = max([v for v in vals if v != -1]) corners = (minpy, miny), (maxx, maxy) ax.update_datalim(corners) ax.autoscale_view() # add these last ax.add_collection(barCollection) return barCollection
def volume_overlay3(ax, quotes, colorup='k', colordown='r', width=4, alpha=1.0): """Add a volume overlay to the current axes. quotes is a list of (d, open, high, low, close, volume) and close-open is used to determine the color of the bar Parameters ---------- ax : `Axes` an Axes instance to plot to quotes : sequence of (time, open, high, low, close, ...) sequences data to plot. time must be in float date format - see date2num width : int the bar width in points colorup : color the color of the lines where close1 >= close0 colordown : color the color of the lines where close1 < close0 alpha : float bar transparency Returns ------- ret : `barCollection` The `barrCollection` added to the axes """ r, g, b = colorConverter.to_rgb(colorup) colorup = r, g, b, alpha r, g, b = colorConverter.to_rgb(colordown) colordown = r, g, b, alpha colord = { True: colorup, False: colordown, } dates, opens, highs, lows, closes, volumes = list(zip(*quotes)) colors = [ colord[close1 >= close0] for close0, close1 in zip(closes[:-1], closes[1:]) if close0 != -1 and close1 != -1 ] colors.insert(0, colord[closes[0] >= opens[0]]) right = width / 2.0 left = -width / 2.0 bars = [((left, 0), (left, volume), (right, volume), (right, 0)) for d, open, high, low, close, volume in quotes] sx = ax.figure.dpi * (1.0 / 72.0) # scale for points sy = ax.bbox.height / ax.viewLim.height barTransform = Affine2D().scale(sx, sy) dates = [d for d, open, high, low, close, volume in quotes] offsetsBars = [(d, 0) for d in dates] useAA = 0, # use tuple here lw = 0.5, # and here barCollection = PolyCollection( bars, facecolors=colors, edgecolors=((0, 0, 0, 1), ), antialiaseds=useAA, linewidths=lw, offsets=offsetsBars, transOffset=ax.transData, ) barCollection.set_transform(barTransform) minpy, maxx = (min(dates), max(dates)) miny = 0 maxy = max([volume for d, open, high, low, close, volume in quotes]) corners = (minpy, miny), (maxx, maxy) ax.update_datalim(corners) #print 'datalim', ax.dataLim.bounds #print 'viewlim', ax.viewLim.bounds ax.add_collection(barCollection) ax.autoscale_view() return barCollection
def volume_overlay(ax, opens, closes, volumes, colorup='k', colordown='r', width=4, alpha=1.0): """Add a volume overlay to the current axes. The opens and closes are used to determine the color of the bar. -1 is missing. If a value is missing on one it must be missing on all Parameters ---------- ax : `Axes` an Axes instance to plot to opens : sequence a sequence of opens closes : sequence a sequence of closes volumes : sequence a sequence of volumes width : int the bar width in points colorup : color the color of the lines where close >= open colordown : color the color of the lines where close < open alpha : float bar transparency Returns ------- ret : `barCollection` The `barrCollection` added to the axes """ r, g, b = colorConverter.to_rgb(colorup) colorup = r, g, b, alpha r, g, b = colorConverter.to_rgb(colordown) colordown = r, g, b, alpha colord = { True: colorup, False: colordown, } colors = [ colord[open < close] for open, close in zip(opens, closes) if open != -1 and close != -1 ] delta = width / 2. bars = [((i - delta, 0), (i - delta, v), (i + delta, v), (i + delta, 0)) for i, v in enumerate(volumes) if v != -1] barCollection = PolyCollection( bars, facecolors=colors, edgecolors=((0, 0, 0, 1), ), antialiaseds=(0, ), linewidths=(0.5, ), ) ax.add_collection(barCollection) corners = (0, 0), (len(bars), max(volumes)) ax.update_datalim(corners) ax.autoscale_view() # add these last return barCollection
def candlestick2_ohlc( ax, opens, highs, lows, closes, width=4, colorup='k', colordown='r', alpha=0.75, ): """Represent the open, close as a bar line and high low range as a vertical line. Parameters ---------- ax : `Axes` an Axes instance to plot to opens : sequence sequence of opening values highs : sequence sequence of high values lows : sequence sequence of low values closes : sequence sequence of closing values ticksize : int size of open and close ticks in points colorup : color the color of the lines where close >= open colordown : color the color of the lines where close < open alpha : float bar transparency Returns ------- ret : tuple (lineCollection, barCollection) """ # note this code assumes if any value open, low, high, close is # missing they all are missing delta = width / 2. barVerts = [((i - delta, open), (i - delta, close), (i + delta, close), (i + delta, open)) for i, open, close in zip(xrange(len(opens)), opens, closes) if open != -1 and close != -1] rangeSegments = [((i, low), (i, high)) for i, low, high in zip(xrange(len(lows)), lows, highs) if low != -1] r, g, b = colorConverter.to_rgb(colorup) colorup = r, g, b, alpha r, g, b = colorConverter.to_rgb(colordown) colordown = r, g, b, alpha colord = { True: colorup, False: colordown, } colors = [ colord[open < close] for open, close in zip(opens, closes) if open != -1 and close != -1 ] assert (len(barVerts) == len(rangeSegments)) useAA = 0, # use tuple here lw = 0.5, # and here rangeCollection = LineCollection( rangeSegments, colors=((0, 0, 0, 1), ), linewidths=lw, antialiaseds=useAA, ) barCollection = PolyCollection( barVerts, facecolors=colors, edgecolors=((0, 0, 0, 1), ), antialiaseds=useAA, linewidths=lw, ) minx, maxx = 0, len(rangeSegments) miny = min([low for low in lows if low != -1]) maxy = max([high for high in highs if high != -1]) corners = (minx, miny), (maxx, maxy) ax.update_datalim(corners) ax.autoscale_view() # add these last ax.add_collection(barCollection) ax.add_collection(rangeCollection) return rangeCollection, barCollection