Forums

plotly and jquery.AJAX not rendering charts

I have this module with function that I am calling with jquery.Ajax()

import pandas_datareader.data as web
from datetime import datetime
import plotly.offline as offline
import plotly.graph_objs as go
import pandas as pd


def plot_watchlist(query_data):

start = datetime(2015, 1, 1)
end = datetime(2015, 11, 1)

plots = []

for row in query_data:

    ticker = row['code_ticker']
    source = row['source']
    #name = row['name']
    f = web.DataReader([ticker], source, start, end)
    #Prepare x and y data to be ploted
    y_data = f['Close'][ticker]
    x_data = pd.to_datetime(f['Close'].index.values)
    stock_chart = offline.plot({
            "data": [go.Scatter(x=x_data,y=y_data)]
        }, output_type="div", showlink = False)
    plots.append(stock_chart)

return (plots)

This function is called within:

@app.route('/getWatchlist'):
def getWatchlist():

          ....
          (some query to get the data)
           ...
           plots = plot_watchlist(query_data)

This is supposed to create a list of plots that get returned and rendered.

I've added print statements inside getWatchlist( ) function (which prints something) and inside plot_watchlist(query_data) which does not print anything.

Any suggestions or ideas about it? Also, any recommendations/alternative to plotly? Is it better to explore plotly.js instead of plotly in python? Other plotting packages like HighCharts?

This is my js script that triggers the function.

$(function() {
    $.ajax({
        url: '/getWatchlist',
        type: 'GET',
        success: function(res) {
            var div = $('<div>')
                .attr('class', 'charts');

            var chartObj = JSON.parse(res);

            var chart = '';

            $.each(chartObj, function(index, value) {
                chart = $(div).clone();
                $(chart).html(value);
                $('.charts').append(chart);
            });
        },
        error: function(error) {
            console.log(error);
        }
    });
});

I have a local copy of the code and runs fine in my machine (renders plots as expected) Thank you!

does nothing show up even if you log at the first line of plot_watchlist?

bfg - as a matter of fact, it does log something when I include a "print" statement before the line below:

   stock_chart = offline.plot({
        "data": [go.Scatter(x=x_data,y=y_data)]
    }, output_type="div", showlink = False)

After this line nothing prints. interestingly enough, I have 2 rows of data in the query_data...so 2 iterations. But if I put a "print" statement inside the loop before this offline.plot function above, only one of the print statements, the 1st one, will execute.

So, I think the problem might be with the function itself...but it is weird I am not getting an error, it seems to just exit the loop...

what is the result from out_type='div'? (do you know what it tries to do?)

bfg - as per the documentation plotly offline, output_type = 'div' returns a string that just contains the HTML <div> that contains the graph and the script to generate the graph. After generating the charts with the plot_watchlist function and creating the list of html <div> I am attempting to render those into the HTML template with the javascript function.

Right- I'm wondering how it's making this html div. Have you ever seen what this div looks like? eg: is it getting data from some cloud plotly offline server? Or is it somehow squishing all the info into the div? (that actually doesn't sound too likely)

What wouldn't work would be if plotly offline actually runs a server locally behind the scenes to allow the html div to get the data and display a chart. In this case then that server won't be available externally/might be unresponsive.

I think is the latter - when I tried printing the offline.plot object before is just a bunch of lines in between the <div> tags <div> a bunch of text, I can actually see the values, etc. </div>

Also, apologies if I am creating confusion. I am very new to web development and trying to learn along the way. I feel like I have been jumping the gun before debugging things in depth. Last night, I was looking at the console log and the error I am getting is "Uncaught Syntax Error: Unexpected token < in JSON ...". This error is prompted during line

var chartObj = JSON.parse(res);

Doing some research I saw that this might be related to the way I am passing the json data with:

 return json.dumps(plots)

at the end of getWatchlist() function, and how I am trying to parse it with JSON.parse(res). I've tempered with these as well, without success. Any suggestions on how I should be passing the data/parsing it in this case?

Thank you advance!

ah- so maybe just console.log res to see what it says?

the console shows all the html text... /getWatchlist only returns json.dumps(plots) ...so shouldn't it just show the plot data or html in this case in the console?

Also, I've tried specifying dataType: 'html' and then I get an error message in the console - Error 90 - message is too long

Also, tried dataType: 'json': and get the error "is not json serializable"

Thank you for the continued support!

From the code and the discussion so far, I would say that if you're returning html from getWatchlist, then you shouldn't be parsing it as JSON, because it's not JSON. I would suggest following your data from the start to the end - what does the plot function return -> what does getWatchlist return -> what does your javascript receive -> what does your javascript put in the page.

Sorry for the delay, but I got this working this past week. I mainly did some housekeeping and cleaned the code. One of the major issues(I believe...since I am very new to JavaScript) is that I was calling the javascript script in the head of the html...and since my function is appending the charts to the division id="charts"...I think that was part of the issue.

  $('.charts').append(chart)

Other than that, I really did not change much on the other parts of the code. In the plot_watchlist I just removed space and new line characters within the plot function and that seem to do the trick.

Thank you for all the suggestions and answers!