def plot_bargraph (self, data, cats=None, config={}): """ Plot a horizontal bar graph. Expects a 2D dict of sample data. Also can take info about categories. There are quite a few variants of how to use this function, see CONTRIBUTING.md for documentation and examples. :param data: 2D dict, first keys as sample names, then x:y data pairs Can supply a list of dicts and will have buttons to switch :param cats: optional list, dict or OrderedDict with plot categories :param config: optional dict with config key:value pairs :return: HTML and JS, ready to be inserted into the page """ # Given one dataset - turn it into a list if type(data) is not list: data = [data] # Check we have a list of cats if type(cats) is not list or type(cats[0]) is str: cats = [cats] # Check that we have cats at all - find them from the data for idx, cat in enumerate(cats): if cats[idx] is None: cats[idx] = list(set(k for s in data[idx].keys() for k in data[idx][s].keys() )) # Given a list of cats - turn it into a dict for idx, cat in enumerate(cats): if type(cat) is list: newcats = OrderedDict() for c in cat: newcats[c] = {'name': c} cats[idx] = newcats # Parse the data into a HighCharts friendly format plotsamples = list() plotdata = list() for idx, d in enumerate(data): hc_samples = sorted(list(d.keys())) hc_data = list() for c in cats[idx].keys(): thisdata = list() for s in hc_samples: try: thisdata.append(d[s][c]) except KeyError: pass if max(thisdata) > 0: thisdict = { 'name': cats[idx][c]['name'], 'data': thisdata } if 'color' in cats[idx][c]: thisdict['color'] = cats[idx][c]['color'] hc_data.append(thisdict) plotsamples.append(hc_samples) plotdata.append(hc_data) # Build the HTML if config.get('id') is None: config['id'] = 'mqc_hcplot_'+''.join(random.sample(letters, 10)) html = '<div class="mqc_hcplot_plotgroup">' # Counts / Percentages Switch if config.get('cpswitch') is not False: if config.get('cpswitch_c_active', True) is True: c_active = 'active' p_active = '' else: c_active = '' p_active = 'active' config['stacking'] = 'percent' c_label = config.get('cpswitch_counts_label', 'Counts') p_label = config.get('cpswitch_percent_label', 'Percentages') html += '<div class="btn-group switch_group"> \n\ <button class="btn btn-default btn-sm {c_a}" data-action="set_numbers" data-target="{id}">{c_l}</button> \n\ <button class="btn btn-default btn-sm {p_a}" data-action="set_percent" data-target="{id}">{p_l}</button> \n\ </div> '.format(id=config['id'], c_a=c_active, p_a=p_active, c_l=c_label, p_l=p_label) if len(plotdata) > 1: html += ' ' # Buttons to cycle through different datasets if len(plotdata) > 1: html += '<div class="btn-group switch_group">\n' for k, p in enumerate(plotdata): active = 'active' if k == 0 else '' try: name = config['data_labels'][k] except: name = k+1 try: ylab = 'data-ylab="{}"'.format(config['data_labels'][k]['ylab']) except: ylab = 'data-ylab="{}"'.format(name) if name != k+1 else '' html += '<button class="btn btn-default btn-sm {a}" data-action="set_data" {y} data-newdata="{k}" data-target="{id}">{n}</button>\n'.format(a=active, id=config['id'], n=name, y=ylab, k=k) html += '</div>\n\n' # Plot and javascript function html += '<div class="hc-plot-wrapper"><div id="{id}" class="hc-plot not_rendered hc-bar-plot"><small>loading..</small></div></div> \n\ </div> \n\ <script type="text/javascript"> \n\ mqc_plots["{id}"] = {{ \n\ "plot_type": "bar_graph", \n\ "samples": {s}, \n\ "datasets": {d}, \n\ "config": {c} \n\ }} \n\ </script>'.format(id=config['id'], s=json.dumps(plotsamples), d=json.dumps(plotdata), c=json.dumps(config)); return html
def plot_bargraph(self, data, cats=None, config={}): """ Plot a horizontal bar graph. Expects a 2D dict of sample data. Also can take info about categories. There are quite a few variants of how to use this function, see CONTRIBUTING.md for documentation and examples. :param data: 2D dict, first keys as sample names, then x:y data pairs Can supply a list of dicts and will have buttons to switch :param cats: optional list, dict or OrderedDict with plot categories :param config: optional dict with config key:value pairs :return: HTML and JS, ready to be inserted into the page """ # Given one dataset - turn it into a list if type(data) is not list: data = [data] # Check we have a list of cats if type(cats) is not list or type(cats[0]) is str: cats = [cats] # Check that we have cats at all - find them from the data for idx, cat in enumerate(cats): if cats[idx] is None: cats[idx] = list( set(k for s in data[idx].keys() for k in data[idx][s].keys())) # Given a list of cats - turn it into a dict for idx, cat in enumerate(cats): if type(cat) is list: newcats = OrderedDict() for c in cat: newcats[c] = {'name': c} cats[idx] = newcats # Parse the data into a HighCharts friendly format plotsamples = list() plotdata = list() for idx, d in enumerate(data): hc_samples = sorted(list(d.keys())) hc_data = list() for c in cats[idx].keys(): thisdata = list() for s in hc_samples: try: thisdata.append(d[s][c]) except KeyError: pass if max(thisdata) > 0: thisdict = {'name': cats[idx][c]['name'], 'data': thisdata} if 'color' in cats[idx][c]: thisdict['color'] = cats[idx][c]['color'] hc_data.append(thisdict) plotsamples.append(hc_samples) plotdata.append(hc_data) # Build the HTML if config.get('id') is None: config['id'] = 'mqc_hcplot_' + ''.join(random.sample(letters, 10)) html = '<div class="mqc_hcplot_plotgroup">' # Counts / Percentages Switch if config.get('cpswitch') is not False: if config.get('cpswitch_c_active', True) is True: c_active = 'active' p_active = '' else: c_active = '' p_active = 'active' config['stacking'] = 'percent' c_label = config.get('cpswitch_counts_label', 'Counts') p_label = config.get('cpswitch_percent_label', 'Percentages') html += '<div class="btn-group switch_group"> \n\ <button class="btn btn-default btn-sm {c_a}" data-action="set_numbers" data-target="{id}">{c_l}</button> \n\ <button class="btn btn-default btn-sm {p_a}" data-action="set_percent" data-target="{id}">{p_l}</button> \n\ </div> '.format(id=config['id'], c_a=c_active, p_a=p_active, c_l=c_label, p_l=p_label) if len(plotdata) > 1: html += ' ' # Buttons to cycle through different datasets if len(plotdata) > 1: html += '<div class="btn-group switch_group">\n' for k, p in enumerate(plotdata): active = 'active' if k == 0 else '' try: name = config['data_labels'][k] except: name = k + 1 try: ylab = 'data-ylab="{}"'.format( config['data_labels'][k]['ylab']) except: ylab = 'data-ylab="{}"'.format( name) if name != k + 1 else '' html += '<button class="btn btn-default btn-sm {a}" data-action="set_data" {y} data-newdata="{k}" data-target="{id}">{n}</button>\n'.format( a=active, id=config['id'], n=name, y=ylab, k=k) html += '</div>\n\n' # Plot and javascript function html += '<div class="hc-plot-wrapper"><div id="{id}" class="hc-plot not_rendered hc-bar-plot"><small>loading..</small></div></div> \n\ </div> \n\ <script type="text/javascript"> \n\ mqc_plots["{id}"] = {{ \n\ "plot_type": "bar_graph", \n\ "samples": {s}, \n\ "datasets": {d}, \n\ "config": {c} \n\ }} \n\ </script>'.format(id=config['id'], s=json.dumps(plotsamples), d=json.dumps(plotdata), c=json.dumps(config)) return html
def plot_xy_data(self, data, config={}): """ Plot a line graph with X,Y data. See CONTRIBUTING.md for further instructions on use. :param data: 2D dict, first keys as sample names, then x:y data pairs :param config: optional dict with config key:value pairs. See CONTRIBUTING.md :return: HTML and JS, ready to be inserted into the page """ # Given one dataset - turn it into a list if type(data) is not list: data = [data] # Generate the data dict structure expected by HighCharts series plotdata = list() for d in data: thisplotdata = list() for s in sorted(d.keys()): pairs = list() maxval = 0 if 'categories' in config: config['categories'] = list() for k in d[s].keys(): config['categories'].append(k) pairs.append(d[s][k]) maxval = max(maxval, d[s][k]) else: for k in sorted(d[s].keys()): pairs.append([k, d[s][k]]) maxval = max(maxval, d[s][k]) if maxval > 0 or config.get('hide_empty') is not True: this_series = { 'name': s, 'data': pairs } try: this_series['color'] = config['colors'][s] except: pass thisplotdata.append(this_series) plotdata.append(thisplotdata) # Add on annotation data series try: for s in config['extra_series']: plotdata[0].append(s) except KeyError: pass # Build the HTML for the page if config.get('id') is None: config['id'] = 'mqc_hcplot_'+''.join(random.sample(letters, 10)) html = '<div class="mqc_hcplot_plotgroup">' # Buttons to cycle through different datasets if len(plotdata) > 1: html += '<div class="btn-group switch_group">\n' for k, p in enumerate(plotdata): active = 'active' if k == 0 else '' try: name = config['data_labels'][k]['name'] except: name = k+1 try: ylab = 'data-ylab="{}"'.format(config['data_labels'][k]['ylab']) except: ylab = 'data-ylab="{}"'.format(name) if name != k+1 else '' html += '<button class="btn btn-default btn-sm {a}" data-action="set_data" {y} data-newdata="{k}" data-target="{id}">{n}</button>\n'.format(a=active, id=config['id'], n=name, y=ylab, k=k) html += '</div>\n\n' # The plot div html += '<div class="hc-plot-wrapper"><div id="{id}" class="hc-plot not_rendered hc-line-plot"><small>loading..</small></div></div></div> \n'.format(id=config['id']) # Javascript with data dump html += '<script type="text/javascript"> \n\ mqc_plots["{id}"] = {{ \n\ "plot_type": "xy_line", \n\ "datasets": {d}, \n\ "config": {c} \n\ }} \n\ </script>'.format(id=config['id'], d=json.dumps(plotdata), c=json.dumps(config)); return html
def plot_xy_data(self, data, config={}): """ Plot a line graph with X,Y data. See CONTRIBUTING.md for further instructions on use. :param data: 2D dict, first keys as sample names, then x:y data pairs :param config: optional dict with config key:value pairs. See CONTRIBUTING.md :return: HTML and JS, ready to be inserted into the page """ # Given one dataset - turn it into a list if type(data) is not list: data = [data] # Generate the data dict structure expected by HighCharts series plotdata = list() for d in data: thisplotdata = list() for s in sorted(d.keys()): pairs = list() maxval = 0 if 'categories' in config: config['categories'] = list() for k in d[s].keys(): config['categories'].append(k) pairs.append(d[s][k]) maxval = max(maxval, d[s][k]) else: for k in sorted(d[s].keys()): pairs.append([k, d[s][k]]) maxval = max(maxval, d[s][k]) if maxval > 0 or config.get('hide_empty') is not True: this_series = {'name': s, 'data': pairs} try: this_series['color'] = config['colors'][s] except: pass thisplotdata.append(this_series) plotdata.append(thisplotdata) # Add on annotation data series try: for s in config['extra_series']: plotdata[0].append(s) except KeyError: pass # Build the HTML for the page if config.get('id') is None: config['id'] = 'mqc_hcplot_' + ''.join(random.sample(letters, 10)) html = '<div class="mqc_hcplot_plotgroup">' # Buttons to cycle through different datasets if len(plotdata) > 1: html += '<div class="btn-group switch_group">\n' for k, p in enumerate(plotdata): active = 'active' if k == 0 else '' try: name = config['data_labels'][k]['name'] except: name = k + 1 try: ylab = 'data-ylab="{}"'.format( config['data_labels'][k]['ylab']) except: ylab = 'data-ylab="{}"'.format( name) if name != k + 1 else '' html += '<button class="btn btn-default btn-sm {a}" data-action="set_data" {y} data-newdata="{k}" data-target="{id}">{n}</button>\n'.format( a=active, id=config['id'], n=name, y=ylab, k=k) html += '</div>\n\n' # The plot div html += '<div class="hc-plot-wrapper"><div id="{id}" class="hc-plot not_rendered hc-line-plot"><small>loading..</small></div></div></div> \n'.format( id=config['id']) # Javascript with data dump html += '<script type="text/javascript"> \n\ mqc_plots["{id}"] = {{ \n\ "plot_type": "xy_line", \n\ "datasets": {d}, \n\ "config": {c} \n\ }} \n\ </script>'.format(id=config['id'], d=json.dumps(plotdata), c=json.dumps(config)) return html