0

I am unable to figure out how to create a NVD3 chart (stackedArea) in Python from a Pandas Dataframe using the python-nvd3 wrapper. A demo with a list of integers is working without issues.

My intitial Data consists a series of dates and a series of values (float):

type(df['Value'])
Out[85]: pandas.core.series.Series

type(df['Start'])
Out[86]: pandas.core.series.Series

type(df['Value'][1])
Out[96]: numpy.float64

type(df['Start'][1])
Out[102]: pandas.tslib.Timestamp

I convert both series to lists and the TimeStamp ('Start') to a string.

type(df['Start'].dt.strftime('%Y-%m-%d %H:%M:%S').tolist())
Out[100]: list

type(df['Value'].values.tolist())
Out[101]: list

The reason I convert the TimeStamp object string is because when I directly supply it, I get the following error message in Django:

Timestamp('2016-02-05 00:00:00') is not JSON serializable

However, the chart remains empty. The length of both list is similar.

The initial data:

df['Start'].dt.strftime('%Y-%m-%d %H:%M:%S').tolist()
Out[104]: 
['2016-02-05 00:00:00',
 '2016-02-05 01:00:00',
 '2016-02-05 02:00:00',
 '2016-02-05 03:00:00',
 '2016-02-05 04:00:00',
 '2016-02-05 05:00:00',
 '2016-02-05 06:00:00',
 '2016-02-05 07:00:00',
 '2016-02-05 08:00:00',
 '2016-02-05 09:00:00',
 '2016-02-05 10:00:00',
 '2016-02-05 11:00:00',
 '2016-02-05 12:00:00',
 '2016-02-05 13:00:00',
 '2016-02-05 14:00:00',
 '2016-02-05 15:00:00',
 '2016-02-05 16:00:00',
 '2016-02-05 17:00:00',
 '2016-02-05 18:00:00',
 '2016-02-05 19:00:00',
 '2016-02-05 20:00:00',
 '2016-02-05 21:00:00',
 '2016-02-05 22:00:00',
 '2016-02-05 23:00:00',
 '2016-02-05 00:00:00',
 '2016-02-05 01:00:00',
 '2016-02-05 02:00:00',
 '2016-02-05 03:00:00',
 '2016-02-05 04:00:00',
 '2016-02-05 05:00:00',
 '2016-02-05 06:00:00',
 '2016-02-05 07:00:00',
 '2016-02-05 08:00:00',
 '2016-02-05 09:00:00',
 '2016-02-05 10:00:00',
 '2016-02-05 11:00:00',
 '2016-02-05 12:00:00',
 '2016-02-05 13:00:00',
 '2016-02-05 14:00:00',
 '2016-02-05 15:00:00',
 '2016-02-05 16:00:00',
 '2016-02-05 17:00:00',
 '2016-02-05 18:00:00',
 '2016-02-05 19:00:00',
 '2016-02-05 20:00:00',
 '2016-02-05 21:00:00',
 '2016-02-05 22:00:00',
 '2016-02-05 23:00:00']


df['Value'].values.tolist()
Out[105]: 
[7330.75,
 7127.5,
 6994.75,
 7116.75,
 7636.0,
 8329.5,
 9193.0,
 10152.5,
 11091.5,
 11851.75,
 12329.75,
 12674.0,
 12800.75,
 12707.75,
 12641.75,
 12783.5,
 13210.0,
 13593.5,
 13842.75,
 13869.5,
 13901.0,
 13984.0,
 13986.5,
 13998.5,
 0.0,
 0.0,
 0.0,
 0.0,
 0.0,
 0.0,
 11.25,
 355.0,
 1256.5,
 2398.75,
 3148.25,
 3171.5,
 2814.25,
 2200.0,
 1319.0,
 440.5,
 17.25,
 0.0,
 0.0,
 0.0,
 0.0,
 0.0,
 0.0,
 0.0]

As requested the relevant code as part of a Django project: views.py

from django.shortcuts import render_to_response, RequestContext
from datetime import date, timedelta
from random import randint

from random import shuffle, randint
from itertools import islice
from django.utils.translation import ugettext_lazy as _

import random
import requests
from requests_ntlm import HttpNtlmAuth
import time
import datetime
from json2html import *
import json
from pandas.io.json import json_normalize
import pandas as pd
import numpy as np


def demo_stackedareachart(request):
    """
    stackedareachart page
    """
    input_start = datetime.date.today() + datetime.timedelta(days=1)
    input_end = datetime.date.today() + datetime.timedelta(days=2)

    parameters={'start':'today+1','end':'today+1','timeZone':'UCT','resolution':'Hour','filterTimeBy':'ValueTime', 'dataPointsToReturn':'All','getSamples':'false'}

    seriesID = 2194
    seriesID2 = 2193

    session = requests.Session()
    session.auth = HttpNtlmAuth('XXXX\\XXXX','XXXXXXXXXXXX', session)
    session.headers={"content-type":"application/json"}
    r = session.get('XXXXXXXXXXX' + str(seriesID) + "%2C" + str(seriesID2), params=parameters, stream=False)

    js = r.json()
    df = json_normalize(js, 'DataPoints',['SeriesId','SamplingTime'])
    df['SamplingTime'] = pd.to_datetime(pd.Series(df['SamplingTime']))
    df['Start'] = pd.to_datetime(pd.Series(df['Start']))

    nb_element = 150

    xdata = df['Start'].values.astype('int64')
    xdata = map(long, xdata)

    ydata = df['Value'].values.tolist()

    extra_serie1 = {"tooltip": {"y_start": "", "y_end": " balls"}}

    chartdata = {
        'x': xdata,
        'name1': 'series 1', 'y1': ydata, 'extra1': extra_serie1,
        # 'name2': 'series 2', 'y2': ydata2, 'extra2': extra_serie2,
    }

    charttype = "stackedAreaChart"
    chartcontainer = 'stackedareachart_container'  # container name
    data = {
        'charttype': charttype,
        'chartdata': chartdata,
        'chartcontainer': chartcontainer,
        'extra': {
            'x_is_date': True,
            'x_axis_format': '%d %m %Y %H %M %S',
            'tag_script_js': True,
            'jquery_on_ready': False,
        },
    }
    return render_to_response('stackedareachart.html', data)

stackedareachart.html

{% extends "__base.html" %}


 {% block content %}

    {% load static %}


{% load nvd3_tags %}
<head>
    {# Jquery CDN : Needed when using jquery_on_ready=True #}
    <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
    {% include_chart_jscss %}
    {% load_chart charttype chartdata chartcontainer extra %}
</head>
<body>
    {% include_container chartcontainer 400 600 %}
</body>



{% endblock %}

UPDATE 1: I made progress by converting the Timestamp to int64 and then to long. The only problem left is, that it returns the same values regardless of the day, resulting in this plot.As you can see the data is stacked "on-top" rather then side-by-side

UPDATE 2: So I assume it all boils down to correctly converting df['Start'] to the correct Integer. But I am stuck at finding the correct syntax. This is what I got so far:

xdata = df['Start'].dt.to_pydatetime()
xdata = map(lambda x: int(time.mktime(q[x].timetuple())*1000), q)

But I fail at the second command.

IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices
lammy
  • 457
  • 2
  • 5
  • 22
  • Python-NVD3 provides and easy python wrapper around this JS library. Please see it. https://github.com/areski/python-nvd3 – oz123 Feb 04 '16 at 14:41
  • I am using that one. I should, of course, have mentioned that in my question. – lammy Feb 04 '16 at 14:45
  • so can you post your code ? not just the pandas stuff? – oz123 Feb 04 '16 at 14:50
  • Thank you for your response. The code is part of a large Django project with several thousand lines and the data is from a non-public Api. I would say that the entire code is not feasible and I think it would not help to re-create the problem. – lammy Feb 04 '16 at 15:19
  • You don't need to post the whole code, just the relevant stuff with Python nvd3... – oz123 Feb 04 '16 at 17:04
  • I added the complete code as requested. – lammy Feb 05 '16 at 15:33

0 Answers0