html 如何正确过滤模型以更新Django中的Plotly图?

gmxoilav  于 2023-01-15  发布在  Go
关注(0)|答案(1)|浏览(185)

日安!
我试着根据一个小例子建立一个图表plotly根据数据从模型
然后我尝试使日期间隔可选。创建了一个表单并将其内置到模板中。
从模板中的这个表单,我在视图代码中按开始和结束日期获取数据。
接下来,我将尝试根据从模板中检索到的日期范围过滤模型中的数据。
并基于来自模型的过滤数据,"更新"模板上的图形。
但是我得到一个错误-Plotly没有得到更新绘图所需的数据列表。
如果你有任何信息,我将非常感激。我已经使用了许多选项来解决这个问题,但不幸的是没有一个工作对我来说。我真的很感激任何帮助。你可能会发现这个代码中的错误。

ValueError: Cannot accept list of column references or list of columns for both `x` and `y`.

模板

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <form method="GET" action="{% url 'chart' %}">

        {{ form.as_p }}

        <button>Submit</button>

    </form>

    {{ chart|safe }}

</body>
</html>

表格

from datetime import date
from django import forms
from .models import *

class DateForm(forms.Form):
    start = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}))
    end = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}))

模型

from django.db import models

# Create your models here.

class Monitoring(models.Model):
    id = models.IntegerField(primary_key=True)
    date = models.DateTimeField()
    nomerkot = models.IntegerField()
    nomerkotla = models.IntegerField()
    tnv = models.IntegerField()
    rashod = models.IntegerField()
    temppod = models.IntegerField()
    tempobr = models.IntegerField()
    tempuhod = models.IntegerField()
    davlgas = models.FloatField()
    davlvos = models.IntegerField()
    virob = models.IntegerField()

视图

from django.shortcuts import render
import plotly.express as px

import csv
from datetime import date
from itertools import islice
from django.conf import settings

import pandas as pd

from .models import *

from .forms import *

def chart(request):
    dict_from_csv = pd.read_csv('demo/dannye.csv', header=0, sep=';', decimal=",")
    dict_from_csv['date'] = pd.to_datetime(dict_from_csv['date'], dayfirst=True)
    dict_from_csv['davlgas'] = pd.to_numeric(dict_from_csv['davlgas'])

    monitoring = Monitoring.objects.all()

    date_x = dict_from_csv['date'].to_numpy()
    date_y = dict_from_csv['temppod'].to_numpy().tolist()

    start = request.GET.get('start')
    start = pd.to_datetime(start)
    end = request.GET.get('end')
    end = pd.to_datetime(end)

    sortirovka = Monitoring.objects.filter(date__gte=start,date__lte=end)

    fig = px.line(
        x=[c.date for c in sortirovka],
        y=[c.temppod for c in sortirovka]
    )

    fig.update_layout(title = {
        "font_size": 22,
        "xanchor": "center",
        "x": 0.5
    })

    chart = fig.to_html()

    context = {'chart': chart, 'form': DateForm()}
    return render(request, 'demo/chart.html', context)

网址

from django.urls import path
from . import views
from . import forms

urlpatterns = [
    path('', views.chart, name='chart')
]
gpfsuwkq

gpfsuwkq1#

这不是一个django的问题,问题只存在于以下几行中:

sortirovka = Monitoring.objects.filter(date__gte=start,date__lte=end)

    fig = px.line(
        x=[c.date for c in sortirovka],
        y=[c.temppod for c in sortirovka]
    )

您正在向xy传递一个由列表解析创建的列表。我不确定,但我不认为列表是精心设计的“类似数组”的列表。
x(str或int或Series或array_like)-data_frame中的列名称,或者PandasSeries或array_like对象。此列或array_like中的值用于沿着笛卡尔坐标中的x轴定位标记。x或y可以是列引用或array_like的列表,在这种情况下,数据将被视为“宽”而不是“长”。(source
试着事先用一个列表单独创建情节,我认为这是行不通的。
猜猜你会输入一个numpy数组或者一个panda序列,这就可以了,在the examples中,他们总是输入一个 Dataframe ,xy也是指向你所引用的列的指针。
我刚刚想到-先试试这个:我猜xy接受包含多个列表的列表,因为这是输入多个数据序列的方式,而您只有一个数据序列,所以尝试以下操作:

fig = px.line(
        x=[[c.date for c in sortirovka],],
        y=[[c.temppod for c in sortirovka],]
    )

相关问题