散景图“超出范围的浮点值不符合JSON”问题

时间:2019-06-18 21:35:31

标签: python plot bokeh

我尝试使用bokeh来建立热图。但是我一直收到相同的错误。我将在下面同时包含我的代码和错误,请帮帮我!

我认为错误主要是由于我的数据中的Nan,所以我在代码中添加了必要的if语句,以确保已解决此问题。甚至尝试在以下列表中用零填充任何可能的Na:“用户”,“模块”,“比率”,“颜色”和“字母”。但是这些更改都没有帮助。

colors = ['#ff0000','#ff1919','#ff4c4c','#ff7f7f','#99cc99','#7fbf7f','#4ca64c','#329932','#008000'] sorted_userlist = list(total_checks_sorted.index) user = [] module = [] ratio = [] color = [] alpha = []

for m_id in ol_module_ids:
    pset = m_id.split('/')[-1]
    col_name1 = m_id + '_ratio'
    col_name2 = m_id + '_total'
    min_checks = min(check_matrix[col_name2].values)
    max_checks = max(check_matrix[col_name2].values)
    for i, u in enumerate(sorted_userlist): 
        module.append(pset)
        user.append(str(i+1))
        ratio_value = check_matrix[col_name1][u]
        ratio.append(ratio_value)

        al= math.sqrt((check_matrix[col_name2][u]-min_checks+0.0001)/float(max_checks))
        if ratio_value>0.16:
            al = min(al*100,1)
        alpha.append(al)
        if np.isnan(ratio_value):
            color.append(colors[0])
        else:
            color.append(colors[int(ratio_value*8)])

#fill NAs in source lists with zeroes pd.Series(ratio).fillna(0).tolist()

col_source = ColumnDataSource(data = dict(module = module, user = user, color=color, alpha=alpha, ratio = ratio))
#source = source.fillna('')        
#TOOLS = "resize,hover,save,pan,box_zoom,wheel_zoom" TOOLS = "reset,hover,save,pan,box_zoom,wheel_zoom"


p=figure(title="Ratio of Correct Checks Each Student Each Online Homework Problem",
    x_range=pset, 
    #y_range = list(reversed(sorted_userlist)),
    y_range=list(reversed(list(map(str, range(1,475))))),
    x_axis_location="above", plot_width=900, plot_height=4000,
    toolbar_location="left", tools=TOOLS)
    #axis_line_color = None)
    #outline_line_color = None)#

p.rect("module", "user", 1, 1, source=col_source,
    color="color", alpha = 'alpha', line_color=None)

show(p)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-33-d2b769a58021> in <module>
     69 #])
     70 
---> 71 show(p)

/Users/azizdridi/anaconda3/lib/python3.7/site-packages/bokeh/io/showing.py in show(obj, browser, new, notebook_handle, notebook_url)
    140         return run_notebook_hook(state.notebook_type, 'app', obj, state, notebook_url)
    141 
--> 142     return _show_with_state(obj, state, browser, new, notebook_handle=notebook_handle)
    143 
    144 #-----------------------------------------------------------------------------

/Users/azizdridi/anaconda3/lib/python3.7/site-packages/bokeh/io/showing.py in _show_with_state(obj, state, browser, new, notebook_handle)
    174 
    175     if state.notebook:
--> 176         comms_handle = run_notebook_hook(state.notebook_type, 'doc', obj, state, notebook_handle)
    177         shown = True
    178 

/Users/azizdridi/anaconda3/lib/python3.7/site-packages/bokeh/io/notebook.py in run_notebook_hook(notebook_type, action, *args, **kw)
    299     if _HOOKS[notebook_type][action] is None:
    300         raise RuntimeError("notebook hook for %r did not install %r action" % notebook_type, action)
--> 301     return _HOOKS[notebook_type][action](*args, **kw)
    302 
    303 #-----------------------------------------------------------------------------

/Users/azizdridi/anaconda3/lib/python3.7/site-packages/bokeh/io/notebook.py in show_doc(obj, state, notebook_handle)
    507     from ..embed.notebook import notebook_content
    508     comms_target = make_id() if notebook_handle else None
--> 509     (script, div, cell_doc) = notebook_content(obj, comms_target)
    510 
    511     publish_display_data({HTML_MIME_TYPE: div})

/Users/azizdridi/anaconda3/lib/python3.7/site-packages/bokeh/embed/notebook.py in notebook_content(model, notebook_comms_target, theme)
     83     # has models with the same IDs as they were started with
     84     with OutputDocumentFor([model], apply_theme=theme, always_new=True) as new_doc:
---> 85         (docs_json, [render_item]) = standalone_docs_json_and_render_items([model])
     86 
     87     div = div_for_render_item(render_item)

/Users/azizdridi/anaconda3/lib/python3.7/site-packages/bokeh/embed/util.py in standalone_docs_json_and_render_items(models, suppress_callback_warning)
    294     docs_json = {}
    295     for doc, (docid, _) in docs.items():
--> 296         docs_json[docid] = doc.to_json()
    297 
    298     render_items = []

/Users/azizdridi/anaconda3/lib/python3.7/site-packages/bokeh/document/document.py in to_json(self)
    842         # this is a total hack to go via a string, needed because
    843         # our BokehJSONEncoder goes straight to a string.
--> 844         doc_json = self.to_json_string()
    845         return loads(doc_json)
    846 

/Users/azizdridi/anaconda3/lib/python3.7/site-packages/bokeh/document/document.py in to_json_string(self, indent)
    871         }
    872 
--> 873         return serialize_json(json, indent=indent)
    874 
    875     def validate(self):

/Users/azizdridi/anaconda3/lib/python3.7/site-packages/bokeh/core/json_encoder.py in serialize_json(obj, pretty, indent, **kwargs)
    159         indent = 2
    160 
--> 161     return json.dumps(obj, cls=BokehJSONEncoder, allow_nan=False, indent=indent, separators=separators, sort_keys=True, **kwargs)
    162 
    163 

/Users/azizdridi/anaconda3/lib/python3.7/json/__init__.py in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
    236         check_circular=check_circular, allow_nan=allow_nan, indent=indent,
    237         separators=separators, default=default, sort_keys=sort_keys,
--> 238         **kw).encode(obj)
    239 
    240 

/Users/azizdridi/anaconda3/lib/python3.7/json/encoder.py in encode(self, o)
    197         # exceptions aren't as detailed.  The list call should be roughly
    198         # equivalent to the PySequence_Fast that ''.join() would do.
--> 199         chunks = self.iterencode(o, _one_shot=True)
    200         if not isinstance(chunks, (list, tuple)):
    201             chunks = list(chunks)

/Users/azizdridi/anaconda3/lib/python3.7/json/encoder.py in iterencode(self, o, _one_shot)
    255                 self.key_separator, self.item_separator, self.sort_keys,
    256                 self.skipkeys, _one_shot)
--> 257         return _iterencode(o, 0)
    258 
    259 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,

ValueError: Out of range float values are not JSON compliant

1 个答案:

答案 0 :(得分:1)

NaN值不可JSON序列化(这是JSON标准的明显缺陷)。您提到ratio列表中有NaN个值,您将它们放在此处的ColumnDataSource中:

col_source = ColumnDataSource(data=dict(..., ratio=ratio))

由于它位于CDS中,因此Bokeh会尝试对其进行序列化,从而导致错误。您有两种选择:

  • 如果由于某种原因(例如,驱动悬停工具或自定义映射器之类的东西)而实际上并不需要在绘图中使用数字ratio,则只需将其保留在数据源之外

  • 如果确实需要发送ratio值,则必须将数据放入NumPy数组中。 Bokeh使用不同的非JSON方法序列化NumPy数组,因此可以成功发送NaN。