Exemple #1
0
def time_series(x_key, y_key, groups, labels, config):
    """Plot time series with error bands per group."""
    # pylint:disable=too-many-function-args
    kwargs = dict(y_axis_type="log") if config["log_scale"] else {}
    pic = figure(title="Plot", **kwargs)
    pic.xaxis.axis_label = x_key
    pic.yaxis.axis_label = y_key

    pic.tools = [
        PanTool(),
        BoxZoomTool(),
        WheelZoomTool(dimensions="height"),
        WheelZoomTool(dimensions="width"),
        SaveTool(),
        ResetTool(),
        HelpTool(),
    ]
    pic.add_tools()
    if config["individual"]:
        pic.add_tools(
            HoverTool(tooltips=[("y", "@y"), ("x", "@x{a}"), ("id", "@id")]))
    else:
        pic.add_tools(HoverTool(tooltips=[("y", "@y_mean"), ("x", "@x{a}")]))

    for label, group, color in zip(labels, groups,
                                   bokeh.palettes.cividis(len(labels))):
        data = group.extract()
        progresses = [d.progress for d in data if y_key in d.progress.columns]
        if not progresses:
            continue

        x_all, all_ys = filter_and_interpolate(x_key, y_key, progresses)

        if config["individual"]:
            plot_individual(pic, x_all, all_ys, data, label, color)
        else:
            plot_mean_dispersion(
                pic,
                x_all,
                all_ys,
                label,
                color,
                standard_error=config["standard_error"],
            )

    pic.legend.location = "bottom_left"
    pic.legend.click_policy = "hide"
    return pic
            var para2 = document.createElement("br");
            document.body.appendChild(para2);

        }
        
        
    """)

    box = BoxSelectTool(callback=boxtoolcallback)

    help_b = HelpTool(help_tooltip="""
        Button fuctions:\n

        Pan: Move around plot\n
        Lasso Select: View plot of artists in selection\n
        Box Select: Listen to all songs in selection\n
        Wheel Zoom: Resize plot\n
        Tap (Click): Listen to all overlaping songs\n
        Hover: Listen, view album cover and title\n
        Reset\n
        """)

    wheel_zoom = WheelZoomTool()
    lasso_select = LassoSelectTool()

    p2 = figure(width=700, height=700)
    p1 = figure(tools=[
        hover, lasso_select, "reset", tap, wheel_zoom, box, "pan", help_b
    ],
                toolbar_location="right",
                toolbar_sticky=False,
            var para2 = document.createElement("br");
            document.body.appendChild(para2);

        }
        
        
    """)

    box = BoxSelectTool(callback=boxtoolcallback)

    help_b = HelpTool(help_tooltip="""
        Button fuctions:

        Click and Drag: Move around plot
        Lasso Select: View plot of artists in selection
        Box Select: Listen to all songs in selection
        Wheel Zoom: Resize plot
        Tap: Listen to all overlaping songs
        Hover: Listen, view album cover and title
        Reset
        """)

    wheel_zoom = WheelZoomTool()

    p1 = figure(tools=[
        hover, "lasso_select", "reset", tap, wheel_zoom, box, "pan", help_b
    ],
                title="Music Collections",
                width=700,
                height=700)
    p1.circle('x',
Exemple #4
0
def draw_plot(G, query, expr, type='publications'):
    # plot
    plot = figure(
        x_range=Range1d(-1.1, 1.1), y_range=Range1d(-1.1, 1.1),
        sizing_mode="stretch_both",
        tools="")
    plot.axis.visible = False
    plot.xgrid.grid_line_color = None
    plot.ygrid.grid_line_color = None

    # legend
    plot.circle(
        x=[-200000, ], y=[-200000, ],
        fill_color='white', size=0, line_width=0,
        legend_label='Visualization for "' + query + '"')
    plot.circle(
        x=[-200000, ], y=[-200000, ],
        fill_color='white', size=0, line_width=0,
        legend_label='created using Microsoft Academic Graph and')
    plot.circle(
        x=[-200000, ], y=[-200000, ],
        fill_color='white', size=0, line_width=0,
        legend_label='Sciencegraph by Marcus Ossiander, 2020')

    if type == 'publications':
        plot.circle(
            x=[-200000, ], y=[-200000, ],
            fill_color=cm2[3], size=20,
            legend_label='Publication, Color measures Citation Count')
        plot.circle(
            x=[-200000, ], y=[-200000, ],
            fill_color=cm1[3], size=10,
            legend_label='Reference, Color measures Citation Count')
    if type == 'authors':
        plot.circle(
            x=[-200000, ], y=[-200000, ],
            fill_color=cm2[3], size=15,
            legend_label='Publication, Color measures Citation Count')
        plot.circle(
            x=[-200000, ], y=[-200000, ],
            fill_color=cm1[3], size=10,
            legend_label='Co-Author, Color measures Collaboration')
    plot.legend.background_fill_alpha = 0
    plot.legend.border_line_alpha = 0
    plot.legend.location = 'top_left'

    # tools
    node_hover_tool = HoverTool(tooltips=tooltips)
    zoom_tool = WheelZoomTool()

    div = Div(
        text='<div id="showpaper" style="position: absolute; display: none; width=500px"></div>',
        name='showpaper', sizing_mode="stretch_width")
    tap_tool_open = TapTool()
    tap_tool_open.callback = CustomJS(
        args={'tp': showpaper_content}, code=code)
    help_tool = HelpTool(
        help_tooltip='Created using Microsoft Academic Graph and Sciencegraph by Marcus Ossiander, 2020',
        redirect='https://github.com/marcus-o/sciencegraph/')
    plot.add_tools(
        node_hover_tool,
        zoom_tool,
        BoxZoomTool(),
        ResetTool(),
        tap_tool_open,
        help_tool)
    plot.toolbar.active_scroll = zoom_tool

    # graph
    graph_renderer = from_networkx(
        G, nx.spring_layout, scale=1, center=(0, 0), seed=12345)
    # normal
    graph_renderer.node_renderer.glyph = Circle(
        size="size", fill_color="color")
    graph_renderer.edge_renderer.glyph = MultiLine(
        line_alpha=0.2)
    # selection
    graph_renderer.node_renderer.selection_glyph = Circle(
        fill_color="color", fill_alpha=1, line_alpha=1)
    graph_renderer.edge_renderer.selection_glyph = MultiLine(
        line_width=3, line_alpha=1)
    graph_renderer.node_renderer.nonselection_glyph = Circle(
        fill_color="color", fill_alpha=0.5, line_alpha=0.5)
    graph_renderer.edge_renderer.nonselection_glyph = MultiLine(
        line_alpha=0.2)
    # hover
    graph_renderer.node_renderer.hover_glyph = Circle(
        fill_color='#abdda4')
    graph_renderer.edge_renderer.hover_glyph = MultiLine(
        line_color='#abdda4', line_width=3)
    graph_renderer.inspection_policy = NodesAndLinkedEdges()
    graph_renderer.selection_policy = NodesAndLinkedEdges()

    # add everything
    plot.renderers.append(graph_renderer)
    script, div = components(Column(children=[plot, div], sizing_mode="stretch_both"))
    return script, div
def bokeh_2d(ids_dict, save_to, load_from_data, load_from_clusters,
             load_from_metadata, audio_path, **curr_params_data):

    df_data = pd.read_csv(load_from_data, names=['UniqueID', 'f1', 'f2'])
    df_clusters = pd.read_csv(load_from_clusters, names=['UniqueID', 'label'])
    df_metadata = pd.read_csv(load_from_metadata,
                              names=['UniqueID', 'file_path', 'artist'])
    df_plot = df_data.join(df_clusters.set_index('UniqueID'), on='UniqueID')
    df_plot = df_plot.join(df_metadata.set_index('UniqueID'), on='UniqueID')

    uid = df_plot['UniqueID'].values
    x = df_plot['f1'].values
    y = df_plot['f2'].values
    label = df_plot['label'].values
    artist = df_plot['artist'].values
    display_name = np.array([get_key(x, ids_dict) for x in uid])

    color_vals = [
        "olive", "darkred", "goldenrod", "skyblue", "red", "darkblue", "gray",
        "indigo", "black"
    ]
    color = np.array([color_vals[l] for l in label])
    audio = np.array(
        [os.path.join('..', audio_path, iD + '.wav') for iD in uid])
    images = np.array([])

    output_file(save_to)

    s1 = ColumnDataSource(data=dict(
        x=x,
        y=y,
        uid=uid,
        desc=audio,
        dsp=display_name,
        arts=artist,  #imgs=images, dsp=display_names,
        colors=color))

    hovertoolcallback = CustomJS(args=dict(source=s1),
                                 code="""
		
		var uids = source.data['uid'];
	    const indices = cb_data.index.indices;
	    if (indices.length > 0){
		    for (i=1; i<indices.length; i++){
		    	//console.log(uids[indices[i]]);
		    	var element = document.getElementById(uids[indices[i]]);
				element.parentNode.removeChild(element);
		    }
		}
		""")
    hover = HoverTool(callback=hovertoolcallback,
                      attachment='below',
                      tooltips="""
	    <div id="@uid">
	    	
	        <img
	            src="@imgs" height="120" alt="@imgs" width="120" style="display: block; margin-left: auto; margin-right: auto;"
	            border="2"
	        ></img>
	        <audio
	            src="@desc" height="20" width="20" autoplay 
	            border="2"
	        ></audio>
	    </div>
	    <p align="center" style="display: block; width: 320px;">@dsp</p>
	    
	    """)
    tap_box_toolcallback = CustomJS(args=dict(source=s1),
                                    code="""

		var sources = source.data['desc'];
	    var names = source.data['dsp'];
	    var inds = source['selected']['1d'].indices;

	    for (i=0; i<inds.length; i++){

	        var title = names[inds[i]];
	        var source = sources[inds[i]];

	        var para = document.createElement("p");
	        var node = document.createTextNode(title);
	        para.appendChild(node);
	        document.body.appendChild(para);

	        var x = document.createElement("AUDIO");
	        var song = String(title);
	        x.setAttribute("src",source);
	        x.setAttribute("controls", "controls");

	        document.body.appendChild(x);

	        var para2 = document.createElement("br");
	        document.body.appendChild(para2);

	    }   
		""")
    tap = TapTool(callback=tap_box_toolcallback)
    box = BoxSelectTool(callback=tap_box_toolcallback)
    help_b = HelpTool(help_tooltip="""
	    Button fuctions:

	    Pan: Move around plot
	    Lasso Select: View plot of artists in selection
	    Box Select: Listen to all songs in selection
	    Wheel Zoom: Resize plot
	    Tap (Click): Listen to all overlaping songs
	    Hover: Listen, view album cover and title
	    Reset
	    """)
    wheel_zoom = WheelZoomTool()
    lasso_select = LassoSelectTool()

    p2 = figure(width=700, height=700)
    p1 = figure(tools=[
        hover, tap, box, lasso_select, help_b, wheel_zoom, "pan", "reset"
    ],
                toolbar_location="right",
                toolbar_sticky=False,
                title="Music Collections",
                width=700,
                height=700)

    p1.circle('x',
              'y',
              source=s1,
              size=7.3,
              fill_alpha=0.5,
              fill_color='colors',
              line_color='colors')
    p1.title.text_font_size = '12pt'
    p1.title.align = 'center'
    p1.toolbar.active_scroll = wheel_zoom
    p1.toolbar.active_drag = lasso_select

    s2 = ColumnDataSource(
        data=dict(artists=[], counts=[], full_artists=[], full_counts=[]))

    s1.callback = CustomJS(args=dict(s2=s2),
                           code="""

		console.log(cb_obj);

		if (document.getElementById("source_d3js")==null){
            var d3js = document.createElement('script');
            d3js.src = "https://d3js.org/d3.v3.min.js";
            d3js.charset = "utf-8";
            d3js.id = "source_d3js";
            document.head.appendChild(d3js);
        }

	    var inds = cb_obj.selected['1d'].indices;
	    var d1 = cb_obj.data;
	    var d2 = s2.data;
	    d2['full_artists'] = [];
	    d2['full_counts'] = [];
	    var max_freq = 0;

	    for (i=0; i<inds.length; i++){

	        var current = d1['arts'][inds[i]];

	        if (d2['full_artists'].indexOf(current) == -1){
	            d2['full_artists'].push(d1['arts'][inds[i]]);
	            d2['full_counts'].push(1);
	        }
	        else{
	            d2['full_counts'][d2['full_artists'].indexOf(current)] += 1;
	            if (d2['full_counts'][d2['full_artists'].indexOf(current)] > max_freq){
	            	max_freq = d2['full_counts'][d2['full_artists'].indexOf(current)];
	            }
	        }
	        
	    }

	    console.log(max_freq);

	    d2['artists'] = [];
	    d2['counts'] = [];
	    var thres = max_freq * 0.05;

	    //filter arrays to only include freqs >= 5pcnt of max_freq

	    for (i=0; i<d2['full_artists'].length; i++){

	    	if (d2['full_counts'][i] >= thres){
	    		d2['artists'].push(d2['full_artists'][i]);
	    		d2['counts'].push(d2['full_counts'][i]);
	    	}

	    }


	    s2.change.emit();

	    if (inds.length > 5){


	        if (document.getElementById("right_side_style")==null){
	            var css = ".right_side div {\\n\\tfont: 12px sans-serif;\\n";
	            css = css.concat("\\tbackground-color: white;\\n\\tpadding: 3px;\\n\\tcolor: white;}");
	            var style = document.createElement('style');
	            style.type = 'text/css';
	            style.id = "right_side_style";
	            style.appendChild(document.createTextNode(css));
	            document.head.appendChild(style);
	        }

	        if (document.getElementById("chart_style")==null){
	            var css = ".chart div {\\n\\tfont: 12px sans-serif;\\n";
	            css = css.concat("\\tbackground-color: steelblue;\\n\\topacity: 0.8;\\n\\theight: 14px;\\n\\tmargin: 1px;\\n\\twidth: 470px;\\n\\ttext-align: right;\\n\\tcolor: white;}");
	            var style = document.createElement('style');
	            style.type = 'text/css';
	            style.id = "chart_style";
	            style.appendChild(document.createTextNode(css));
	            document.head.appendChild(style);
	        }

	        if (document.getElementById("artist_style")==null){
	            var css = ".artists div {\\n\\tfont: 12px sans-serif;\\n";
	            css = css.concat("\\tbackground-color: white;\\n\\theight: 14px;\\n\\tmargin: 1px;\\n\\twidth: 470px;\\n\\ttext-align: right;\\n\\tcolor: black;}");
	            var style = document.createElement('style');
	            style.type = 'text/css';
	            style.id = "artist_style";
	            style.appendChild(document.createTextNode(css));
	            document.head.appendChild(style);
	        }

	        if (document.getElementById("right_side_div")==null){
	            var rightdiv = document.createElement('div');
	            rightdiv.className = "right_side";
	            rightdiv.style = "float: left; position: absolute; top: 10px; left: 720px; width: 970px;";
	            rightdiv.id = "right_side_div";
	            //document.getElementsByClassName("bk-root")[0].innerHTML = "";
	            //document.getElementsByClassName("bk-root")[0].style = "width: 970px";
	            document.getElementsByClassName("bk-root")[0].appendChild(rightdiv);
	        }
	        else{
	        	//document.getElementsByClassName("bk-spacer-box bk-layout-fixed")[0].style = "width: 970px";
	            document.getElementById("right_side_div").innerHTML = "";
	        }

	        if (document.getElementById("title_p")==null){
	            var para = document.createElement("p");
	            var node = document.createTextNode("Artist Frequencies");
	            para.className = "title";
	            para.style = "text-align: center; font-weight: bold; font-size: 15px;";
	            para.id = "title_p";
	            para.appendChild(node);
	            document.getElementsByClassName("right_side")[0].appendChild(para);
	        }
	        else{
	            document.getElementById("artists_div").innerHTML = "";
	        }

	        if (document.getElementById("artists_div")==null){
	            var artdiv = document.createElement('div');
	            artdiv.className = "artists";
	            artdiv.style = "float: left; tdisplay: inline-flex;";
	            artdiv.id = "artists_div";
	            document.getElementsByClassName("right_side")[0].appendChild(artdiv);
	        }
	        else{
	            document.getElementById("artists_div").innerHTML = "";
	        }

	        if (document.getElementById("chart_div")==null){
	            var chartdiv = document.createElement('div');
	            chartdiv.className = "chart";
	            chartdiv.style = "float: right; tdisplay: inline-flex;";
	            chartdiv.id = "chart_div";
	            document.getElementsByClassName("right_side")[0].appendChild(chartdiv);
	        }
	        else{
	            document.getElementById("chart_div").innerHTML = "";
	        }


	        if (document.getElementById("source_d3js")==null){
	            var d3js = document.createElement('script');
	            d3js.src = "https://d3js.org/d3.v3.min.js";
	            d3js.id = "source_d3js";
	            document.head.appendChild(d3js);
	        }


	        if (document.getElementById("mycode")==null){
	            var code_div = document.createElement('script');
	            code_div.id = "mycode";
	            document.body.appendChild(code_div);
	        }

	        //populate var data with d2["counts"] and var art_names with d2["artists"]

	        var string = "[";

	        for (j=0; j<d2['counts'].length-1; j++){
	        	var tmp = d2['counts'][j];
	            string = string.concat(tmp);
	            string += ", ";
	        }
	        
	        var tmp = d2['counts'][d2['counts'].length-1];
	        string = string.concat(tmp);
	        string += "]";


	        var string1 = "[\\"";

	        for (j=0; j<d2['artists'].length-1; j++){
	            var tmp = d2['artists'][j];
	            string1 = string1.concat(tmp);
	            string1 = string1.concat("\\"")
	            string1 += ", \\"";
	        }
	        
	        var tmp = d2['artists'][d2['artists'].length-1];
	        string1 = string1.concat(tmp);
	        string1 += "\\"]";


	        var d3js_code = "var data = ";
	        d3js_code = d3js_code.concat(string);
	        d3js_code = d3js_code + ";\\n\\n";

	        d3js_code = d3js_code+ "var art_names = ";
	        d3js_code = d3js_code.concat(string1);
	        d3js_code = d3js_code + ";\\n\\n";


	        d3js_code = d3js_code.concat("var x = d3.scale.linear()\\n    .domain([0, d3.max(data)])\\n    .range([0, 470]);\\n\\n");
	        //    var x = d3.scale.linear()
	        //        .domain([0, d3.max(data)])
	        //        .range([0, 420]);

	        
	        d3js_code = d3js_code.concat("d3.select(\\".chart\\")\\n  .selectAll(\\"div\\")\\n    "+
	        ".data(data)\\n  .enter().append(\\"div\\")\\n    "+
	        ".style(\\"width\\", function(d) { return x(d) + \\"px\\"; })\\n    .text(function(d) { return d; });");

	        //    d3.select(".chart")
	        //      .selectAll("div")
	        //        .data(data)
	        //      .enter().append("div")
	        //        .style("width", function(d) { return x(d) + "px"; })
	        //        .style("margin", "auto 5px")
	        //        .text(function(d) { return d; });";
	        //        .class("chartel");


	        
	        d3js_code = d3js_code.concat("\\n\\nd3.select(\\".artists\\")\\n  .selectAll(\\"div\\")\\n    "+
	        ".data(art_names)\\n  .enter().append(\\"div\\")\\n    "+
	        ".style(\\"width\\", \\"300\\")\\n    .text(function(d) { return d; });");

	        //    d3.select(".artists")
	        //      .selectAll("div")
	        //        .data(art_names)
	        //      .enter().append("div")
	        //        .style("width", "300")
	        //        .style("margin", "auto 5px")
	        //        .text(function(d) { return d; });";
	        //        .class("artel");

	        document.getElementById("mycode").innerHTML = "";
	        document.getElementById("mycode").appendChild(document.createTextNode(d3js_code));


	        var script = document.getElementById("mycode");	        
	        eval(script.innerHTML);


	        // Check if chart and script exist
	        // if not, create them
	        // if they are, change innerhtml for script
	        // delete nodes from char and repopulate with new data    

	    }

	    """)

    grid = gridplot([[p1, None]], merge_tools=False)
    show(grid)
Exemple #6
0
def visualize(request, product_id):
    product = Products.objects.get(pk=product_id)
    comments = Comment.objects.select_related().filter(product=product_id)
    # bar chart based on age
    fif_twenP = 0
    fif_twenN = 0
    twen_twen5P = 0
    twen_twen5N = 0
    twen5_thirP = 0
    twen5_thirN = 0
    for comment in comments:
        users = User.objects.filter(pk=comment.user_id)
        for user in users:
            age = user.userprofile.age
            if age > 15 and age < 20:
                if comment.polarity == 1:
                    fif_twenP += 1
                else:
                    fif_twenN += 1
            elif age > 20 and age < 25:
                if comment.polarity == 1:
                    twen_twen5P += 1
                else:
                    twen_twen5N += 1
            elif age > 25 and age < 30:
                if comment.polarity == 1:
                    twen5_thirP += 1
                else:
                    twen5_thirN += 1

    age_range = ['15-20', '20-25', '25-30']
    polarity = ['pos', 'neg']

    data = {
        'fruits': age_range,
        'pos': [fif_twenP, twen_twen5P, twen5_thirP],
        'neg': [fif_twenN, twen_twen5N, twen5_thirN],
    }

    # this creates [ ("Apples", "2015"), ("Apples", "2016"), ("Apples", "2017"), ("Pears", "2015), ... ]
    x = [(age, pol) for age in age_range for pol in polarity]
    counts = sum(zip(data['pos'], data['neg']),
                 ())  #sum(zip(data['pos'], data['neg'])) # like an hstack
    colors = ["#c9d9d3", "#718dbf"]
    source = ColumnDataSource(data=dict(x=x, counts=counts))

    p = figure(x_range=FactorRange(*x),
               title=f'{product.title}',
               toolbar_location="below",
               tools="pan,wheel_zoom,box_zoom,reset",
               plot_width=800,
               plot_height=300)
    p.add_tools(HelpTool())
    p.vbar(x='x', top='counts', width=0.9, source=source)

    p.y_range.start = 0
    p.x_range.range_padding = 0.1
    p.legend.label_text_font_size = '40pt'
    p.xaxis.axis_label_text_font_size = '40pt'
    p.yaxis.axis_label_text_font_size = '40pt'
    p.xaxis.major_label_orientation = 1
    p.xgrid.grid_line_color = None

    script, div = components(p)

    #bar chart based on location
    product = Products.objects.get(pk=product_id)
    comments = Comment.objects.select_related().filter(product=product_id)

    kath_P = 0
    kath_N = 0
    lalit_P = 0
    lalit_N = 0
    bkt_P = 0
    bkt_N = 0
    chit_P = 0
    chit_N = 0
    gor_P = 0
    gor_N = 0
    ilam_P = 0
    ilam_N = 0
    for comment in comments:
        users = User.objects.filter(pk=comment.user_id)
        for user in users:
            location = user.userprofile.location
            if location == "Kathmandu":
                if comment.polarity == 1:
                    kath_P += 1
                else:
                    kath_N += 1
            elif location == "Lalitpur":
                if comment.polarity == 1:
                    lalit_P += 1
                else:
                    lalit_N += 1
            elif location == "Bhaktapur":
                if comment.polarity == 1:
                    bkt_P += 1
                else:
                    bkt_N += 1
            elif location == "Chitwan":
                if comment.polarity == 1:
                    chit_P += 1
                else:
                    chit_N += 1
            elif location == "Gorkha":
                if comment.polarity == 1:
                    gor_P += 1
                else:
                    gor_N += 1
            elif location == "Ilam":
                if comment.polarity == 1:
                    ilam_P += 1
                else:
                    ilam_N += 1

    location = [
        'Kathmandu', 'Lalitpur', 'Bhaktapur', 'Chitwan', 'Gorkha', 'Illam'
    ]
    polarity = ['pos', 'neg']

    data = {
        'fruits': location,
        'pos': [kath_P, lalit_P, bkt_P, chit_P, gor_P, ilam_P],
        'neg': [kath_N, lalit_N, bkt_N, chit_N, gor_N, ilam_N],
    }

    # this creates [ ("Apples", "2015"), ("Apples", "2016"), ("Apples", "2017"), ("Pears", "2015), ... ]
    x = [(loc, pol) for loc in location for pol in polarity]
    counts = sum(zip(data['pos'], data['neg']),
                 ())  #sum(zip(data['pos'], data['neg'])) # like an hstack
    colors = ["#c9d9d3", "#718dbf"]
    source = ColumnDataSource(data=dict(x=x, counts=counts))

    p_loc = figure(x_range=FactorRange(*x),
                   title=f'{product.title}',
                   toolbar_location="below",
                   tools="pan,wheel_zoom,box_zoom,reset",
                   plot_width=800,
                   plot_height=300)
    p_loc.add_tools(HelpTool())

    p_loc.vbar(x='x', top='counts', width=0.9, source=source)

    p_loc.y_range.start = 0
    p_loc.x_range.range_padding = 0.1
    p_loc.xaxis.major_label_orientation = 1
    p_loc.xgrid.grid_line_color = None
    p_loc.legend.label_text_font_size = '40pt'

    script, div = components(p)
    script1, div1 = components(p_loc)

    return render(request, 'visualize/plot.html', {
        'script': script,
        'div': div,
        'script1': script1,
        'div1': div1
    })
# Add start tick
source = ColumnDataSource(dict(x=[0, 0], y=[track_inner_radius, track_outer_radius]))
line = Line(x='x', y='y', line_color="black", line_width=2)
plot.add_glyph(source, line)

# Add tooltip
features_tooltip = [
    ("Start base", "@start_location"),
    ("End base", "@end_location"),
    ("Type", "@type"),
    ("Locus tag", "@locus_tag"),
    ("Strand", "@strand")
]

# Set renderers=[features] so that the tooltip appears only for Annular Wedge glpyhs
features_hovertool = HoverTool(renderers=[features], tooltips=features_tooltip, point_policy='follow_mouse')

#Add tools to the plot; create a document; add the plot to it
plot.add_tools(WheelZoomTool(), PreviewSaveTool(), ResetTool(), HelpTool(), PanTool(), features_hovertool)
doc = Document()
doc.add(plot)


if __name__ == "__main__":
    filename = "test.html"
    with open(filename, "w") as f:
        f.write(file_html(doc, INLINE, "test"))
    print("Wrote %s" % filename)
    view(filename)