def _single_violin(ax, pos, pos_data, width, side, plot_opts): """""" def _violin_range(pos_data, plot_opts): """Return array with correct range, with which violins can be plotted.""" cutoff = plot_opts.get('cutoff', False) cutoff_type = plot_opts.get('cutoff_type', 'std') cutoff_val = plot_opts.get('cutoff_val', 1.5) s = 0.0 if cutoff: if cutoff_type == 'std': s = cutoff_val * np.std(pos_data) else: s = cutoff_val x_lower = pos_data.min() - s x_upper = pos_data.max() + s return np.linspace(x_lower, x_upper, 100) pos_data = np.asarray(pos_data) # Create violin for pos, scaled to the available space. xvals = _violin_range(pos_data, plot_opts) # Kernel density estimate for data at this position. violin, e = fastkde.fastkde1D(pos_data, len(xvals), extents=[min(xvals), max(xvals)]) xvals = np.linspace(e[0], e[1], len(violin)) violin = width * violin / violin.max() if side == 'both': envelope_l, envelope_r = (-violin + pos, violin + pos) elif side == 'right': envelope_l, envelope_r = (pos, violin + pos) elif side == 'left': envelope_l, envelope_r = (-violin + pos, pos) else: msg = "`side` parameter should be one of {'left', 'right', 'both'}." raise ValueError(msg) # Draw the violin. ax.fill_betweenx(xvals, envelope_l, envelope_r, facecolor=plot_opts.get('violin_fc', 'y'), edgecolor=plot_opts.get('violin_ec', 'k'), lw=plot_opts.get('violin_lw', 1), alpha=plot_opts.get('violin_alpha', 0.5)) return xvals, violin
def kde_plot(x, ax=None, orientation='horizontal', cutoff=False, log=False, cutoff_type='std', cutoff_val=1.5, pos=100, pos_marker='line', pos_width=0.05, pos_kwargs={}, **kwargs): """""" if ax is None: ax = plt.gca() # Massage '_data' for processing. _data = np.asarray(x) # Create violin for pos, scaled to the available space. s = 0.0 if cutoff: if cutoff_type == 'std': s = cutoff_val * np.std(_data) else: s = cutoff_val x_lower = x.min() - s x_upper = x.max() + s # Kernel density estimate for data at this position. violin, e = fastkde.fastkde1D(_data, pos, extents=[x_lower, x_upper]) xvals = np.linspace(e[0], e[1], len(violin)) #violin /= violin.max() # Draw the violin. if ('facecolor' not in kwargs.keys()) | ('fc' not in kwargs.keys()): kwargs['facecolor'] = 'y' if ('edgecolor' not in kwargs.keys()) | ('ec' not in kwargs.keys()): kwargs['edgecolor'] = 'k' if ('alpha' not in kwargs.keys()): kwargs['alpha'] = 0.5 #draw the positions if not 'marker' in pos_kwargs: if pos_marker != 'line': pos_kwargs['marker'] = pos_marker else: pos_kwargs['marker'] = 's' else: pos_marker = pos_kwargs['marker'] if ('facecolor' not in pos_kwargs.keys()) | ('fc' not in pos_kwargs.keys()) | \ ('markerfacecolor' not in pos_kwargs.keys()) | ('mfc' not in pos_kwargs.keys()): pos_kwargs['markerfacecolor'] = 'None' if ('edgecolor' not in kwargs.keys()) | ('ec' not in pos_kwargs.keys()) | \ ('markeredgecolor' not in kwargs.keys()) | ('mec' not in pos_kwargs.keys()): pos_kwargs['markeredgecolor'] = 'k' if ('linestyle' not in pos_kwargs.keys()) | ('ls' not in pos_kwargs.keys()): pos_kwargs['linestyle'] = 'None' if ('size' not in kwargs.keys()) | ('markersize' not in pos_kwargs.keys()): pos_kwargs['markersize'] = 3 if orientation == 'horizontal': ax.fill(xvals, violin, **kwargs) mv = np.max(violin) #Draw the lines if pos_marker is not None: if (pos_marker == 'line') | (pos_marker == 'lines'): pos_kwargs.pop('marker') ax.plot(x, - 0.5 * pos_width * mv * np.ones(len(x)), marker='|', **pos_kwargs) else: ax.plot(x, np.random.uniform(low=-pos_width * mv, high=0., size=len(x)), **pos_kwargs) ax.set_ylim(-pos_width * mv, ax.get_ylim()[1]) plt.draw_if_interactive() elif orientation == 'vertical': ax.fill_betweenx(xvals, 0, violin, **kwargs) #Draw the lines if pos_marker is not None: if (pos_marker == 'line') | (pos_marker == 'lines'): pos_kwargs.pop('marker') ax.plot(-0.5 * pos_width * mv * np.ones(len(x)), x, marker='_', **pos_kwargs) else: ax.plot(np.random.uniform(low=-pos_width * mv, high=0., size=len(x)), x, **pos_kwargs) ax.set_xlim(-pos_width * mv, ax.get_xlim()[1]) plt.draw_if_interactive() return xvals, violin