Python Pygal图表从数据库中提取数据而不是将值与标签匹配

时间:2018-06-07 19:08:12

标签: python database charts pygal

我正在处理我的第一个项目,我正在使用Pygal来显示数据库中的一些数据。

我使用的是最新版本的Python(3.6.5),Flask,Pygal,我的IDE是Pycharm

该项目是一个简单的预算应用程序,其中一个人输入每月支出的计划预算,然后输入该费用/项目的实际金额(例如,每月汽车费用,如汽油)。

我使用Pygal来显示2个条形图。第一个(按预期工作)显示总计划金额与总实际金额:

enter image description here

第二张图表显示了计划与实际每项费用/项目(例如,每月汽车费用,如汽油)

我面临的问题是图表会混淆标签和金额。它们根据输入的顺序显示在图表中,而不是根据项目类型显示。

例如:

enter image description here

在上图中,共有3个项目:Masina(汽车),Salariu(薪水)和Economii(储蓄)。

蓝色列表示的金额(实际金额)应显示在标签Economii下,而不是Masina下,我输入数据作为数据库中的第一个实际数据并不重要。

此外,在数据库中为相同的费用项目(在我们的例子中为Economii)添加更多实际金额只会添加更多列,并且不会在同一列上汇总:

enter image description here

这是我正在使用的数据库查询功能:

def GraphData():
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
db_path = os.path.join(BASE_DIR, 'budget_db.db')
with sqlite3.connect(db_path) as db:
    c = db.cursor()
    d = db.cursor()
    c.execute('SELECT title, category, name, planned_amount_month FROM Post')
    d.execute('SELECT title_actual, category_actual, actual_amount_name, actual_amount FROM ActualPost')
    data_planned = c.fetchall()
    data_actual = d.fetchall()
return data_planned, data_actual

以下是我为这两个图表创建的路线。标签是从title_planned列表中提取的,我感觉我面临的问题是因为我正在创建列表而我正在追加它们。 我想我应该创建词典,但我不知道如何不搞乱其他一切:

 @posts.route("/home")
def graphing():
data_planned, data_actual = GraphData()
title_planned = []
value_planned = []
title_actual = []
value_actual = []
for planned_row in data_planned:
    title_planned.append(planned_row[2])
    value_planned.append(planned_row[3])
for actual_row in data_actual:
    title_actual.append(actual_row[2])
    value_actual.append(actual_row[3])

graph = pygal.Bar(title=u'Total Planned Values vs Total Actual Values')
graph.add('Planned', [{'value': sum(value_planned), 'label': 'Total for Planned Budget:'}])
graph.add('Actual', [{'value': sum(value_actual), 'label': 'Total for Actual Amounts:'}])
graph_data = graph.render_data_uri()

graph_all = pygal.Bar(title=u'Planned Budget per item vs Actual Amounts per item')
graph_all.x_labels = title_planned
graph_all.add('Planned', value_planned)
graph_all.add('Actual', value_actual)
graph_all_data = graph_all.render_data_uri()

return render_template('home.html', graph_data=graph_data, graph_all_data=graph_all_data)

修改

我一直尝试在路线中使用2个词典,费用项目为dict键(title_planned_sum / title_actual_sum),金额为dict值(value_planned_sum / { {1}}):

value_actual_sum

以下是完整路线:

tv_planned = dict(zip(title_planned, value_planned))
tv_planned_sum = {title_planned_sum: sum(value_planned_sum) for title_planned_sum, value_planned_sum in tv_planned.items()}

tv_actual = dict(zip(title_actual, value_actual))
tv_actual_sum = {title_actual_sum: sum(value_actual_sum) for title_actual_sum, value_actual_sum in tv_actual.items()}

但是,当然,现在我收到了这个调试错误:

  

@posts.route("/home") def graphing(): data_planned, data_actual = GraphData() title_planned = [] value_planned = [] title_actual = [] value_actual = [] for planned_row in data_planned: title_planned.append(planned_row[2]) value_planned.append(planned_row[3]) for actual_row in data_actual: title_actual.append(actual_row[2]) value_actual.append(actual_row[3]) tv_planned = dict(zip(title_planned, value_planned)) tv_planned_sum = {title_planned_sum: sum(value_planned_sum) for title_planned_sum, value_planned_sum in tv_planned.items()} tv_actual = dict(zip(title_actual, value_actual)) tv_actual_sum = {title_actual_sum: sum(value_actual_sum) for title_actual_sum, value_actual_sum in tv_actual.items()} graph = pygal.Bar(title=u'Total Planned Values vs Total Actual Values') graph.add('Planned', [{'value': sum(value_planned), 'label': 'Total for Planned Budget:'}]) graph.add('Actual', [{'value': sum(value_actual), 'label': 'Total for Actual Amounts:'}]) graph_data = graph.render_data_uri() graph_all = pygal.Bar(title=u'Planned Budget per item vs Actual Amounts per item') graph_all.x_labels = title_planned graph_all.add('Planned', tv_planned_sum) graph_all.add('Actual', tv_actual_sum) graph_all_data = graph_all.render_data_uri() return render_template('home.html', graph_data=graph_data, graph_all_data=graph_all_data)

这是因为,在我尝试使用的2个词典中,我试图对使用 TypeError: 'float' object is not iterable 接收多个值的每个键的值求和。

1 个答案:

答案 0 :(得分:0)

我开始工作了!

最后我意识到我的问题过于复杂,所以我拿出一支笔和纸,开始做一些伪代码看看我的代码中的第一步,我可以轻松地计算导致我头疼的浮点数。

步骤1:在我的路线中,我可以创建一个包含嵌套元组的列表(每个包含2个元素:str和float)

步骤2:现在,如果某些元组有索引[0]上的元素相同,如何对索引[1]上的浮点元素求和?

所以,我问this question on reddit.com/r/learnpython和用户 diech 给了我一个我可以成功使用的想法:导入itertools包并从中导入groupby()

以下是我的路线代码现在的样子:

@posts.route("/home")
def graphing():
    data_planned, data_actual = GraphData()

    title_planned = []
    value_planned = []
    title_actual = []
    value_actual = []
    planned = []
    actual = []

    for planned_row in data_planned:
        title_planned.append(planned_row[2])
        value_planned.append(planned_row[3])
        planned_list = zip(title_planned, value_planned)
        for key, group in itertools.groupby(sorted(planned_list), lambda  x: x[0]):
            asum = 0
            for i in group:
                asum += i[1]
            planned.append((key, asum))

    planned_dict = dict(planned)

    for actual_row in data_actual:
        title_actual.append(actual_row[2])
        value_actual.append(actual_row[3])
        actual_list = zip(title_actual, value_actual)
        for key, group in itertools.groupby(sorted(actual_list), lambda  x: x[0]):
            asum = 0
            for i in group:
                asum += i[1]
            actual.append((key, asum))

    actual_dict = dict(actual)

    graph = pygal.Bar(title=u'Total Planned Values vs Total Actual Values')
    graph.add('Planned', [{'value': sum(value_planned), 'label': 'Total for Planned Budget:'}])
    graph.add('Actual', [{'value': sum(value_actual), 'label': 'Total for Actual Amounts:'}])
    graph_data = graph.render_data_uri()

    graph_all = pygal.Bar(title=u'Planned Budget per item vs Actual Amounts per item')
    graph_all.x_labels = title_planned
    graph_all.add('Planned', planned_dict)
    graph_all.add('Actual', actual_dict)
    graph_all_data = graph_all.render_data_uri()

    return render_template('home.html', graph_data=graph_data, graph_all_data=graph_all_data)