3

I am trying to make a request to my Django back-end with AJAX. I got the AJAX part working, but I am now trying to return an mpld3 figure to display it on the page.

This is the HTML Form:

               <form id="pointform" method="POST">
                  {% csrf_token %}
                  <div class="row">
                    <div class="col-lg-6 col-md-6">
                      <input name="x_coord" type="text" accept=""id="x_coordinate" class="form-control form-control-md" type="text" placeholder="X-Coordinate">
                    </div>
                    <div class="col-lg-6 col-md-6">
                      <input name="y_coord" type="text" id="y_coordinate" class="form-control form-control-md" type="text" placeholder="Y-Coordinate">
                    </div>
                  </div>
                  <button style="width: 100%" type="submit" class="btn btn-danger">Add Point</button>
              </form>

Here is my AJAX request:

      $.ajax({
          type: "POST",
          url: url,
          data: data,
          dataType: "json",
          success: function(json){

          },            
      });

This is my View:

import mpld3
import matplotlib.pyplot as plt

X = []
y = []

def get_figure(request):

    x_coord = request.POST['X']
    y_coord = request.POST['Y']

    X.append(x_coord)
    y.append(y_coord)

    fig = plt.figure()
    plt.scatter(X, y)
    model = mpld3.fig_to_html(fig)

    data = {'Model': model}

    return JsonResponse(data)

Here is the entire traceback coming from the command line:

File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\site-packages\django\core\handlers\exception.py", line 39, in inner
    response = get_response(request)
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\User\Desktop\mlapp06\regression\views.py", line 24, in get_regression_graph
    fig = plt.figure()
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\site-packages\matplotlib\pyplot.py", line 535, in figure
    **kwargs)
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 81, in new_figure_manager
    return new_figure_manager_given_figure(num, figure)
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 98, in new_figure_manager_given_figure
    icon_img = Tk.PhotoImage(file=icon_fname)
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 3394, in __init__
    Image.__init__(self, 'photo', name, cnf, master, **kw)
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 3350, in __init__
    self.tk.call(('image', 'create', imgtype, name,) + options)
RuntimeError: main thread is not in main loop
[05/Oct/2017 15:54:51] "POST /ajax/get_regression_graph/ HTTP/1.1" 500 18714
Traceback (most recent call last):
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 138, in run
    self.finish_response()
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 180, in finish_response

    self.write(data)
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 274, in write
    self.send_headers()
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 332, in send_headers
    self.send_preamble()
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 255, in send_preamble
    ('Date: %s\r\n' % format_date_time(time.time())).encode('iso-8859-1')
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 453, in _write
    result = self.stdout.write(data)
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\socket.py", line 593, in write
    return self._sock.send(b)
ConnectionAbortedError: [WinError 10053] Eine bestehende Verbindung wurde softwaregesteuert
durch den Hostcomputer abgebrochen
[05/Oct/2017 15:54:51] "POST /ajax/get_regression_graph/ HTTP/1.1" 500 59
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 53724)
Traceback (most recent call last):
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 138, in run
    self.finish_response()
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 180, in finish_response

    self.write(data)
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 274, in write
    self.send_headers()
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 332, in send_headers
    self.send_preamble()
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 255, in send_preamble
    ('Date: %s\r\n' % format_date_time(time.time())).encode('iso-8859-1')
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 453, in _write
    result = self.stdout.write(data)
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\socket.py", line 593, in write
    return self._sock.send(b)
ConnectionAbortedError: [WinError 10053] Eine bestehende Verbindung wurde softwaregesteuert
durch den Hostcomputer abgebrochen

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 141, in run
    self.handle_error()
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\site-packages\django\core\servers\basehttp.py", line 95, in handle_error
    super(ServerHandler, self).handle_error()
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 368, in handle_error
    self.finish_response()
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 180, in finish_response

    self.write(data)
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 274, in write
    self.send_headers()
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 331, in send_headers
    if not self.origin_server or self.client_is_modern():
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 344, in client_is_modern
    return self.environ['SERVER_PROTOCOL'].upper() != 'HTTP/0.9'
TypeError: 'NoneType' object is not subscriptable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\socketserver.py", line 625, in process_request_thread
    self.finish_request(request, client_address)
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\socketserver.py", line 354, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\socketserver.py", line 681, in __init__
    self.handle()
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\site-packages\django\core\servers\basehttp.py", line 174, in handle
    handler.run(self.server.get_app())
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\handlers.py", line 144, in run
    self.close()
  File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\wsgiref\simple_server.py", line 36, in close
    self.status.split(' ',1)[0], self.bytes_sent
AttributeError: 'NoneType' object has no attribute 'split'

Any suggestions on why it could happen?

Thanks in Advance

OhMad
  • 6,871
  • 20
  • 56
  • 85

2 Answers2

4

I guess the code is running on a server, which does not have any graphical output. Hence creating the figure may fail. You may use a non-GUI backend, like

import matplotlib
matplotlib.use("Agg")
import mpld3
import matplotlib.pyplot as plt
# ... rest of code
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
  • Nope, that‘s not it unfortunately. It is running on my localhost. – OhMad Oct 11 '17 at 07:25
  • 1
    localhost is a server. Do you get the same error, when running the above code or a different one? (I would guess it's different, hence it would be good to know the complete error traceback of that one) – ImportanceOfBeingErnest Oct 11 '17 at 08:00
  • It's still the same. – OhMad Oct 11 '17 at 15:13
  • 1
    In that case you don't show the full code. The error in the question is triggered by some `Tkinter` problem, which cannot be there if you use the "Agg" backend. Also there is some `get_regression_graph` in the errortraceback which is not part of the code. You need to make sure to provide a [mcve] of the issue. – ImportanceOfBeingErnest Oct 11 '17 at 15:16
  • I edited the question and added the html and rest of the method to it. I only renamed the get_regression_graph method, it's the same as you see above. – OhMad Oct 11 '17 at 17:09
  • 1
    Do you not get my point? If you use `matplotlib.use("Agg")` you cannot get an error coming from `backend_tkagg.py`. This means that you either get a different error and would need to show it, or that the lines `import matplotlib matplotlib.use("Agg")` are not the first ones in your code, such that they are ignored. – ImportanceOfBeingErnest Oct 11 '17 at 17:12
2

Are you calling this from another thread? TKinter needs to run in the main thread.

Please check whether these similar questions help in solving your problem: RuntimeError: main thread is not in main loop https://www.reddit.com/r/learnpython/comments/69z9fs/error_main_thread_not_in_main_loop/

  • I guess the point is more that you do not actually want to use Tkinter at all when creating a figure for web output. Hence changing the backend, as suggested in my answer, would probably be the route to go. – ImportanceOfBeingErnest Oct 10 '17 at 22:40