Django/plotly.js:将 Pandas 数据框列传递给模板图表

Django/plotly.js: Pass Pandas Dataframe columns to template chart

我有一个 pandas 数据框(不是用户输入)作为 csv 格式存储在我的数据库中。我在我的视图中提取此 csv,然后想将两列传递到我的模板并传递到 plotly.js 图表中:一个日期列和一个值列。我应该如何正确地将它们作为模板变量传递,以便 plotly 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.

识别为 dates/values

我认为我的中途解决方案有点乱七八糟,图表没有正确解释。

这是数据帧的示例:


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. 从数据存储(通常是数据库,但在本例中为 CSV)中获取数据
  2. 将该数据放入模板中
  3. 在JS中解析数据
  4. 密谋

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

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

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


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

因为您可以将 Django 模板视为只是 copy/paste:它会将您的数据粘贴到您放置该标记的任何位置,无论是在 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})