I am trying to convert the Embedding WebAgg script to a Django web app. The plot is displayed but interactive features are not working. For example, when I click the Zoom button I get this error:
in receive
self.manager.handle_json(message)
File "/Users/ils475/.pyenv/versions/mpl/lib/python3.10/site-packages/matplotlib/backends/backend_webagg_core.py", line 464, in handle_json
self.canvas.handle_event(content)
File "/Users/ils475/.pyenv/versions/mpl/lib/python3.10/site-packages/matplotlib/backends/backend_webagg_core.py", line 264, in handle_event
return handler(event)
File "/Users/ils475/.pyenv/versions/mpl/lib/python3.10/site-packages/matplotlib/backends/backend_webagg_core.py", line 319, in handle_toolbar_button
getattr(self.toolbar, event['name'])()
AttributeError: 'NoneType' object has no attribute 'zoom'
Also, there are no X and Y coordinate values displayed under the plot when mouse is hovering over it.
Code
consumers.py
:
import json
from django.core.cache import cache
from channels.generic.websocket import WebsocketConsumer
class WebSocketConsumer(WebsocketConsumer):
def connect(self):
self.accept()
self.manager = cache.get("figure_manager")
self.manager.add_web_socket(self)
def disconnect(self, close_code):
self.manager.remove_web_socket(self)
def receive(self, text_data=None, bytes_data=None):
message = json.loads(text_data)
self.manager.handle_json(message)
def send_json(self, content):
self.send(text_data=json.dumps(content))
def send_binary(self, blob):
self.send(bytes_data=blob)
views.py
:
import mimetypes
import io
from django.core.cache import cache
from django.http import HttpResponse
from django.shortcuts import render
from django.views.decorators.http import require_GET
from matplotlib.backends.backend_webagg_core import (
FigureManagerWebAgg, new_figure_manager_given_figure)
from matplotlib.figure import Figure
import numpy as np
def create_figure():
"""
Creates a simple example figure.
"""
fig = Figure()
ax = fig.add_subplot()
t = np.arange(0.0, 3.0, 0.01)
s = np.sin(2 * np.pi * t)
ax.plot(t, s)
return fig
def index(request):
figure = create_figure()
manager = new_figure_manager_given_figure(id(figure), figure)
cache.set('figure_manager', manager)
ws_uri = f"ws://{request.get_host()}/"
return render(request, 'websocket.html',
{"ws_uri": ws_uri, "fig_id": manager.num})
@require_GET
def mpl_js(request):
response = HttpResponse(content_type='application/javascript')
response.write(FigureManagerWebAgg.get_javascript())
return response
@require_GET
def download(request, fmt):
manager = cache.get("figure_manager")
response = HttpResponse(content_type=mimetypes.types_map.get(fmt, 'binary'))
buff = io.BytesIO()
manager.canvas.figure.savefig(buff, format=fmt)
response.write(buff.getvalue())
return response
routing.py
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws$', consumers.WebSocketConsumer.as_asgi()),
]
Any ideas?