Exemplo n.º 1
0
 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 += ' &nbsp; &nbsp; '
     
     # 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
Exemplo n.º 2
0
    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 += ' &nbsp; &nbsp; '

        # 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
Exemplo n.º 3
0
 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
Exemplo n.º 4
0
    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