Django / plotly.js:将Pandas Dataframe列传递到模板图表

时间:2019-10-27 04:36:36

标签: javascript python django pandas plotly.js

我有一个以csv格式存储在数据库中的pandas数据框(不是用户输入)。我在视图中提取了此csv,然后希望将两列传递到我的模板和plotly.js图表​​中:日期列和值列。我应该如何正确地将它们作为模板变量传递,以使javascript正确地解释它们?

尝试的解决方案:

views.py

def chart_function(request):
       df = #dataframe is extracted from DB using some code
       dates = list(pd.to_datetime(df['dates']))
       values = [float(i) for i in list(df['values'])]
       return render(request, template.html, {'values': values, 'dates': dates})   

template.html:


<div id="myDiv"></div>
<input type = "hidden" id = "dates" name = "variable" value = "{{dates|safe}}">
<input type = "hidden" id = "values" name = "variable" value = "{{values|safe}}">


<script type = "text/javascript">
var dates = document.getElementById("dates").value.split(',');
var values = document.getElementById("values").value.split(',');

var trace1 = {
  x: dates,
  y: values,
  type: 'scatter',
};


var data = [trace1];
Plotly.newPlot('myDiv', data, {}, {showSendToCloud: true});
</script>


该绘图实际上可以正确地绘图,但是很明显,日期没有作为日期对象传递,因为x轴的日期在字符串和方括号内。我需要将df列通过plotly javascript识别为日期/值。

我认为我的中途解决方案有点不合时宜,图表无法正确解释。

以下是数据框的示例:


Date          Value          
2019-01-03    3.0
2019-01-04    4.0
2019-01-05    5.0
2019-01-06    6.0
2019-01-07    7.0
2019-01-08    8.0
2019-01-09    9.0
2019-01-10   10.0
2019-01-11   11.0
2019-01-12   12.0
2019-01-13   13.0
2019-01-14   14.0
2019-01-15   15.0
2019-01-16   16.0


1 个答案:

答案 0 :(得分:0)

您在这里的过程有几个步骤:

  1. 从数据存储(通常是数据库,但在这种情况下为CSV)中获取数据
  2. 将数据放入模板
  3. 解析JS中的数据
  4. 密谋

第1步很棒,但第2步方法有点奇怪。通常,这称为序列化;我强烈建议您不要使用隐藏输入。您的目标是将熊猫数据框转换为JS变量,这比您想象的要简单。

您可以通过将JavaScript更改为以下内容来消除隐藏的输入:

var trace1 = {
  x: {{dates|safe}},
  y: {{values|safe}},
  type: 'scatter',
};


var data = [trace1];
Plotly.newPlot('myDiv', data, {}, {showSendToCloud: true});

因为您可以将Django模板看作只是复制/粘贴:无论您将标记放在HTML还是JS部分中,它将粘贴您的数据。

为了将来参考,Pandas有一个名为df.to_json()的序列化方法,该方法是为此翻译而构建的,并且具有用于控制日期格式和内容的内置选项。那是最好的工具,但是在技术上并不是必须的。文件:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_json.html

对于第三步,plotly期望使用JS Date对象,并且要给它提供字符串-您需要首先使用Date.parse()解析它们

您可以这样做的一种方法是将Date.parse()函数映射到日期字符串数组上,如下所示:

unparsedDates = {{dates|safe}}

parsedDates = unparsedDates.map(dateString => new Date(dateString) )

var trace1 = {
  x: parsedDates,
  y: {{values|safe}},
  type: 'scatter',
};


var data = [trace1];
Plotly.newPlot('myDiv', data, {}, {showSendToCloud: true})