【问题标题】:Loading JSON from Python into DataTable of Google's Annotated Chart将 Python 中的 JSON 加载到 Google 注释图表的 DataTable 中
【发布时间】:2014-02-22 19:14:55
【问题描述】:

我用 python 收集了污染数据并将其存储在 MySQL 表中。 现在我想在 Google 的Annotated charts 之一中显示这个。

当我在网页上显示图表时,通过 web.py 服务器呈现,我得到一个空白图表。 什么都没有,只有空白。它可能是 JSON 字符串的格式化方式,或者我尝试将其加载到 DataTable 对象中的方式。

这是我目前如何将 MySQL 数据转换为 DataTable 对象并使用 Python 和 web.py 将其呈现到网络:

  1. 用python从mysql中查询数据。这将返回:

    [(datetime.datetime(2014, 2, 23, 2, 1, 3), 329),
     (datetime.datetime(2014, 2, 23, 1, 1, 4), 337),
     (datetime.datetime(2014, 2, 23, 0, 1, 5), 353),
     (datetime.datetime(2014, 2, 22, 23, 1, 4), 377),
     (datetime.datetime(2014, 2, 22, 22, 1, 7), 404),
     (datetime.datetime(2014, 2, 22, 21, 1, 5), 402),
     (datetime.datetime(2014, 2, 22, 20, 1, 4), 391),
     (datetime.datetime(2014, 2, 22, 19, 1, 3), 385),
     (datetime.datetime(2014, 2, 22, 18, 1, 3), 389),
     (datetime.datetime(2014, 2, 22, 17, 1, 3), 400)]
    
  2. 然后使用google的gviz_api python库来定义表

    description = [("Time","datetime"),
                   ("PM25 Pollution","number")]
    
  3. 然后创建DataTable对象并加载数据

    data_table = gviz_api.DataTable(description)
    data_table.LoadData(data)
    
  4. 我正在使用 web.py 来渲染所有这些并在网络上获取它,所以我得到了 JSON 字符串:

    return data_table.ToJson()
    
  5. 这是返回的 JSON 字符串:

    {"rows":[{"c":[{"v":"Date(2014,1,23,2,1,3)"},{"v":329}]},{"c":[{"v":"Date(2014,1,23,1,1,4)"},{"v":337}]},{"c":[{"v":"Date(2014,1,23,0,1,5)"},{"v":353}]},{"c":[{"v":"Date(2014,1,22,23,1,4)"},{"v":377}]},{"c":[{"v":"Date(2014,1,22,22,1,7)"},{"v":404}]},{"c":[{"v":"Date(2014,1,22,21,1,5)"},{"v":402}]},{"c":[{"v":"Date(2014,1,22,20,1,4)"},{"v":391}]},{"c":[{"v":"Date(2014,1,22,19,1,3)"},{"v":385}]},{"c":[{"v":"Date(2014,1,22,18,1,3)"},{"v":389}]},{"c":[{"v":"Date(2014,1,22,17,1,3)"},{"v":400}]}],"cols":[{"type":"datetime","id":"Time","label":"Time"},{"type":"number","id":"PM25 Pollution","label":"PM25 Pollution"}]}
    
  6. 然后我将字符串发送到此模板以进行渲染:

    $def with (jsonDataString)
    
    <html>
      <head>
        <script type='text/javascript' src='http://www.google.com/jsapi'></script>
        <script type='text/javascript'>
          google.load('visualization', '1.1', {'packages':['annotationchart']});
          google.setOnLoadCallback(drawChart)
    
          function drawChart() {
            var data = new google.visualization.DataTable($jsonDataString);
    
            var chart = new google.visualization.AnnotationChart(document.getElementById('chart_div'));
    
            var options = {
              displayAnnotations: true,
            };
    
            chart.draw(data, options);
          }
        </script>
      </head>
    
      <body>
        <div id='chart_div' style='width: 900px; height: 500px;'></div>
        <!-- Output the string to see if its there-->
        $jsonDataString
      </body>
    </html>
    

当我加载页面时,看到一个空白区域,900 x 500 像素,然后是上面的 JSON 字符串。所以我知道我得到的 JSON 字符串是什么,但我是图表新手,不确定它的格式是否正确。我没有改变任何东西,只是让 gviz_api Python 库完成工作。

我也试过了:

var data = new google.visualization.DataTable.fromJson($jsonDataString);

但无济于事。

注意:$jsonDataString 被 web.py 模板系统转义,当然替换为上面显示的字符串。

我用谷歌搜索了一下,堆栈溢出,似乎找不到问题所在。如果您有任何建议或意见,他们将不胜感激。如果您认为您可以提供帮助,我会尝试详细说明,但从我在这里写的内容中不太明白。

编辑 #1 有趣的。这实际上是我在 Chrome 中查看源代码时得到的。这是从 web.py 的 Templator 渲染出来的:

    <html>
    <head>
        <script type='text/javascript' src='http://www.google.com/jsapi'></script>
        <script type='text/javascript'>
          google.load('visualization', '1.1', {'packages':['annotationchart']});
          google.setOnLoadCallback(drawChart)

          function drawChart() {
            var data = new google.visualization.DataTable({&quot;rows&quot;:[{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,18,1,4)&quot;},{&quot;v&quot;:383}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,17,1,3)&quot;},{&quot;v&quot;:386}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,16,1,3)&quot;},{&quot;v&quot;:366}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,15,1,4)&quot;},{&quot;v&quot;:333}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,14,1,3)&quot;},{&quot;v&quot;:329}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,13,1,3)&quot;},{&quot;v&quot;:320}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,12,1,3)&quot;},{&quot;v&quot;:316}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,11,1,4)&quot;},{&quot;v&quot;:302}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,10,1,3)&quot;},{&quot;v&quot;:296}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,9,1,3)&quot;},{&quot;v&quot;:296}]}],&quot;cols&quot;:[{&quot;type&quot;:&quot;datetime&quot;,&quot;id&quot;:&quot;Time&quot;,&quot;label&quot;:&quot;Time&quot;},{&quot;type&quot;:&quot;number&quot;,&quot;id&quot;:&quot;PM25 Pollution&quot;,&quot;label&quot;:&quot;PM25 Pollution&quot;}]});

            var chart = new google.visualization.AnnotationChart(document.getElementById('chart_div'));

            var options = {
              displayAnnotations: true,
            };

            chart.draw(data, options);
          }

        </script>
    </head>

    <body>
    <div id='chart_div' style='width: 900px; height: 500px;'></div>
    <!-- Output the string to see if its there-->
    {&quot;rows&quot;:[{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,18,1,4)&quot;},{&quot;v&quot;:383}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,17,1,3)&quot;},{&quot;v&quot;:386}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,16,1,3)&quot;},{&quot;v&quot;:366}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,15,1,4)&quot;},{&quot;v&quot;:333}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,14,1,3)&quot;},{&quot;v&quot;:329}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,13,1,3)&quot;},{&quot;v&quot;:320}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,12,1,3)&quot;},{&quot;v&quot;:316}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,11,1,4)&quot;},{&quot;v&quot;:302}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,10,1,3)&quot;},{&quot;v&quot;:296}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,9,1,3)&quot;},{&quot;v&quot;:296}]}],&quot;cols&quot;:[{&quot;type&quot;:&quot;datetime&quot;,&quot;id&quot;:&quot;Time&quot;,&quot;label&quot;:&quot;Time&quot;},{&quot;type&quot;:&quot;number&quot;,&quot;id&quot;:&quot;PM25
    Pollution&quot;,&quot;label&quot;:&quot;PM25 Pollution&quot;}]}
    </body>
    </html>

我想我明白这里发生了什么。 web.py 的 Templator 必须用 websafe 引号替换 "s。这显然不会与 JS 一起使用。我想所有要做的就是找到如何在 web.py 中禁用 websafe 引号呈现。(或找到其他一些解决方法。)

感谢安托,您的建议。我很傻,没有实际检查输出!

编辑 #2:已解决 为了让 web.py 不呈现 websafe 引号,我只是替换了:

$jsonDataString

$:jsonDataString

在 web.py 模板中。 找到答案here

【问题讨论】:

  • 感谢 Martijn,我是 stackoverflow 标记的新手
  • 列表中的代码块总是有点混乱;您需要将缩进加倍。
  • fyi,使用你的 json 字符串(没有 python)和 html 代码我得到了有效的图表
  • 您能检查一下模板渲染后得到什么代码吗?
  • 好的,我一个小时后到家,把渲染的代码贴出来。

标签: python json google-visualization web.py


【解决方案1】:

我来这里是为了从 (python) pandas 数据帧中获取 -> json -> JavaScript 中的 google.visualization.DataTable ...

#imports
import pandas as pd
import json
# create df for test
cols = ["col1", "col2", "col3"]
vals = [["work",2,3],["play",5,6]]
df = pd.DataFrame(vals, columns=cols)


# Send df to google.visualization.DataTable via json
# ..parse column data (I'm only using numbers and strings)
# ..google allows ['string', 'number', 'boolean', 'date', 'datetime', and 'timeofday']
# ..but no dates for json
# .. ..one-liner here
cols = [{"id": col,
        "label": col,
        "type": "string" if df[col].dtype == 'O' else "number"
        } for col in df.columns]
# ..use pandas to get at the row data
jsdata = json.loads(df.to_json(orient="split"))["data"]
# .. ..multi-liners seem easier to read...
rows = []
for row in jsdata:
    row = [{"v": val} for val in row]
    rows.append({"c": row})

#.. I'm using dumps to show the value but you probably want to use 
#.. dump in practice
to_google = json.dumps({"cols": cols, "rows": rows})
print(to_google)

In [1]:
{"cols": [{"id": "col1", "label": "col1", "type": "string"}, {"id": "col2", "label": "col2", "type": "number"}, {"id": "col3", "label": "col3", "type": "number"}], "rows": [{"c": [{"v": "work"}, {"v": 2}, {"v": 3}]}, {"c": [{"v": "play"}, {"v": 5}, {"v": 6}]}]}

在 .js 方面,关键行是:

// parse the responseText from your xhttp GET
_jsonIn = JSON.parse(xhttp.responseText);
// drop it into your table
dt = new google.visualization.DataTable(_jsonIn);

【讨论】:

    猜你喜欢
    • 2021-07-31
    • 1970-01-01
    • 2021-03-15
    • 1970-01-01
    • 2014-03-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-28
    • 1970-01-01
    相关资源
    最近更新 更多