Проблема с боке: значения с плавающей точкой вне диапазона не соответствуют JSON - PullRequest
0 голосов
/ 07 ноября 2019

В настоящее время я пытаюсь написать программу, которая решает уравнение теплопроводности, используя явный метод конечных разностей, и составляет решения, но я столкнулась с проблемой, которую не смогла исправить самостоятельно.

Не могли бы вы мне помочь?

Только figMass и figEnergy провоцируют эту ошибку, fig отображает нормально.

Вот код и ошибка:

import numpy as np

from bokeh.io import show, output_notebook
from bokeh.plotting import figure
from bokeh.layouts import column, row

output_notebook(hide_banner=True)


L = 10
v = 1
J = 1000
dx = L/(J+1)

def u0(x) :
    return 2 - np.cos(2*np.pi*x/L)


def explicit_method(dt, T) :
    N = int(T/dt)
    r = v*dt/(dx**2)

    #Construction of the recurrence matrix :

    A = np.zeros((J+2, J+2))
    A[0][0], A[0][1] = 1-r, r
    A[-1][-1], A[-1][-2] = 1-r, r
    for i in range(1, J+1) :
        A[i][i], A[i][i-1], A[i][i+1] = 1-2*r, r, r

    #Construction of Un :

    U = np.zeros((J+2,N+1))
    U[:,0] = np.array([u0(j*dx) for j in range(J+2)])
    for n in range(1, N+1) :
        U[:,n] = np.dot(A, U[:,n-1])

    return U_1


x = np.linspace(0, L, J+2)

dt, T = 0.004, 20
N = int(T/dt)

U_1 = np.transpose(explicit_method(dt, T))

fig = figure(title="Conditions aux bords (1)  dt = 0.004", width=490, height=300)
fig.line(x, U_1[0],  color="red", legend="T = 0")
fig.line(x, U_1[N//20],  color="green", legend="T = 1")
fig.line(x, U_1[N//4],  color="blue", legend="T = 5")
fig.line(x, U_1[N],  color="black", legend="T = 20")

Mass = [np.sum(U_1[n]) for n in range(N+1)]

figMass = figure(width=490, height=300)
figMass.line(np.arange(N+1), Mass, legend="Mass")

Energy = [np.linalg.norm(U_1[n]) for n in range(N+1)]

figEnergy = figure(width=490, height=300)
figEnergy.line(np.arange(N+1), Energy,  color="red", legend="Energy")

show(row(fig, figMass, figEnergy))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-e6cf303be061> in <module>
     41 figEnergy.line(np.arange(N+1), Energy,  color="red", legend="Energy")
     42 
---> 43 show(row(fig, figMass, figEnergy))
     44 
     45 print(f"r = {v*dt/(dx**2)}")

~\Miniconda3\envs\map412\lib\site-packages\bokeh\io\showing.py in show(obj, browser, new, notebook_handle, notebook_url, **kw)
    143         return run_notebook_hook(state.notebook_type, 'app', obj, state, notebook_url, **kw)
    144 
--> 145     return _show_with_state(obj, state, browser, new, notebook_handle=notebook_handle)
    146 
    147 #-----------------------------------------------------------------------------

~\Miniconda3\envs\map412\lib\site-packages\bokeh\io\showing.py in _show_with_state(obj, state, browser, new, notebook_handle)
    177 
    178     if state.notebook:
--> 179         comms_handle = run_notebook_hook(state.notebook_type, 'doc', obj, state, notebook_handle)
    180         shown = True
    181 

~\Miniconda3\envs\map412\lib\site-packages\bokeh\io\notebook.py in run_notebook_hook(notebook_type, action, *args, **kw)
    300     if _HOOKS[notebook_type][action] is None:
    301         raise RuntimeError("notebook hook for %r did not install %r action" % notebook_type, action)
--> 302     return _HOOKS[notebook_type][action](*args, **kw)
    303 
    304 #-----------------------------------------------------------------------------

~\Miniconda3\envs\map412\lib\site-packages\bokeh\io\notebook.py in show_doc(obj, state, notebook_handle)
    510     from ..embed.notebook import notebook_content
    511     comms_target = make_id() if notebook_handle else None
--> 512     (script, div, cell_doc) = notebook_content(obj, comms_target)
    513 
    514     publish_display_data({HTML_MIME_TYPE: div})

~\Miniconda3\envs\map412\lib\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)

~\Miniconda3\envs\map412\lib\site-packages\bokeh\embed\util.py in standalone_docs_json_and_render_items(models, suppress_callback_warning)
    295     docs_json = {}
    296     for doc, (docid, _) in docs.items():
--> 297         docs_json[docid] = doc.to_json()
    298 
    299     render_items = []

~\Miniconda3\envs\map412\lib\site-packages\bokeh\document\document.py in to_json(self)
    843         # this is a total hack to go via a string, needed because
    844         # our BokehJSONEncoder goes straight to a string.
--> 845         doc_json = self.to_json_string()
    846         return loads(doc_json)
    847 

~\Miniconda3\envs\map412\lib\site-packages\bokeh\document\document.py in to_json_string(self, indent)
    872         }
    873 
--> 874         return serialize_json(json, indent=indent)
    875 
    876     def validate(self):

~\Miniconda3\envs\map412\lib\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 

~\Miniconda3\envs\map412\lib\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 

~\Miniconda3\envs\map412\lib\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)

~\Miniconda3\envs\map412\lib\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 голосов
/ 07 ноября 2019

Проблема в том, что вы используете простой список Python, содержащий значения NaN:

Energy = [np.linalg.norm(U_1[n]) for n in range(N+1)]

Когда вы используете простой список, он сериализуется как обычный JSON. К сожалению, из-за (IMO) явного недосмотра сама спецификация JSON не поддерживает передачу значений NaN. С этим ничего не поделаешь. Однако Bokeh поддерживает кодирование значений NaN в кодировках, отличных от JSON. Но они доступны только при использовании массивов float32 или float64 NumPy. Вы должны будете поместить свои данные в один из них.

...