【问题标题】:Plotting JSON time series data grouped by category with Pandas and Bokeh使用 Pandas 和 Bokeh 绘制按类别分组的 JSON 时间序列数据
【发布时间】:2020-05-15 10:24:08
【问题描述】:

我有一些每日时间序列 JSON 数据,这些数据涵盖同一文件中的多个站点(底部 JSON 中的单个条目示例)。 我想使用 Bokeh 绘制这些,每个站点的时间序列(按“system_name”分类/分组)作为同一图上的不同颜色的线。如何获得每行的情节?当前的方法是尝试使用multi_line - 是否应该只是使用for 循环的p.line

非常感谢指导/指针。

import json
from datetime import datetime
from pandas.io.json import json_normalize
from bokeh.plotting import figure, output_file, show
from bokeh.models import ColumnDataSource


output_file('wyndham.html')


with open('wyndham_data.txt', 'r') as f:
    a = json.load(f)

res = json_normalize(a['features'])
gby = res.groupby('properties.system_name')


for key, item in gby:
    g = item.sort_values(by='properties.date_stamp')       **<<<works to here**
    source = ColumnDataSource(dict(x = g[['properties.date_stamp']], 
            y = g[['properties.energy_prod(KWh)']]))

p = figure()
p.multi_line(x, y, source=source)
show(p)

示例 JSON:


    {
    "type" : "FeatureCollection",
    "name" : "wyndham-solar-energy-production.json",
    "features" : [
        {
            "type" : "Feature",
            "geometry" : null,
            "properties" : {
                "system_id" : "9386741",
                "system_name" : "Yerambooee Community Centre  ",
                "date_stamp" : "2018-08-01",
                "energy_prod(KWh)" : 51.5,
                "energy_life(MWh)" : null,
                "C02 (Kg)" : 47.41,
                "KWp" : 18.2,
                "performance" : 2.8,
                "lat" : -37.8587717,
                "lon" : 144.7100923,
                "date_installed" : "2017-07-27"
            }

        }, ...

【问题讨论】:

  • 欢迎堆栈溢出!要获得最优质的答案,请尝试缩小范围。关于如何将 json 数据读入 pandas 的问题非常适合堆栈溢出(尽管已经有很多关于该主题的问题)。另外,您可以询问如何创建散景图。关于可视化此类数据的最佳策略的问题可能更多是堆栈交换网络的Software Recommendations 站点的主题。

标签: pandas time-series categories bokeh


【解决方案1】:

你可以这样做来绘制一条线:

import numpy as np
import pandas as pd
from datetime import datetime
import json
import matplotlib.pyplot as plt
import bokeh

with open('1.json', 'r+') as f:
    data = json.load(f)

df = pd.json_normalize(data['features'])
df.index = df['properties.date_stamp']
print(df)
plt.figure()
df.plot()

【讨论】:

  • 我对你导入的 matplotlib 感到困惑?
【解决方案2】:

经过大量的试验和错误,我找到了一种方法来使它工作。 (虽然代码和输出本身并不漂亮 - 它满足了练习的目的)。

线条和颜色的数量超过了散景默认调色板中的颜色数量。 Bokeh.palettes linear_palette 函数允许我为 30 行中的每一行设置一个独特的颜色阴影。

在我发布的问题中,我使用了下载的 JSON 的本地副本,并将其保存到文本文件中。我添加了 import requests 和目标 URL,以防您希望自己运行它。请注意,这在我的机器上运行大约需要 15 秒。截图链接:Wyndham Wind Farm Scheme Daily Ouput Plot.

我还有一个SettingWithCopyWarning

SettingWithCopyWarning: 试图在 DataFrame 中的切片副本上设置一个值。 尝试改用 .loc[row_indexer,col_indexer] = value

请参阅文档中的注意事项:https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy site_data['properties.date_stamp'] = pd.to_datetime(site_data['properties.date_stamp'])

import requests
import pandas as pd
import json
from datetime import datetime
from pandas import json_normalize
from bokeh.plotting import figure, output_file, show
from bokeh.models import ColumnDataSource
from bokeh.palettes import linear_palette, Viridis256

URL = "https://data.gov.au/data/dataset/aa75879c-1d3e-4ad2-b331-826032c6b84b/resource/6e309687-023b-436b-9079-582b7e2fb074/download/wyndham-solar-energy-production.json"

r = requests.get(URL)
a = json.loads(r.text)


res = json_normalize(a['features'])
gby = res.groupby('properties.system_name')
sites = res['properties.system_name'].unique()
num_sites = len(sites)

output_file('wyndham.html')
plot_colors = linear_palette(Viridis256, num_sites)
p = figure(width=1800, height=900, x_axis_type="datetime", 
           title = "Wyndham Wind Farm Scheme Daily Power Output")
p.yaxis.axis_label = "Daily Power Output (kW.h)"

count = 0
for key, grp in gby:
    line_col = plot_colors[count]
    g = grp.sort_values(by='properties.date_stamp')
    site_data = g[['properties.date_stamp','properties.energy_prod(KWh)']]
    site_data['properties.date_stamp'] = pd.to_datetime(site_data['properties.date_stamp'])
    site_cds = ColumnDataSource(site_data) 
    p.line(x=site_data['properties.date_stamp'], y=site_data['properties.energy_prod(KWh)'], 
            legend_label=key, line_width = 2, line_color = line_col)
    count += 1

show(p)

Wyndham Wind Farm Scheme Daily Ouput Plot

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    • 2015-11-15
    • 2020-04-20
    • 2019-04-20
    • 2015-09-10
    • 1970-01-01
    • 2020-06-01
    相关资源
    最近更新 更多