【问题标题】:Error in Django when using matplotlib examples使用 matplotlib 示例时 Django 中的错误
【发布时间】:2018-11-05 03:37:23
【问题描述】:

我正在测试几个 Django 和 matplotlib 的案例,例如 this questionin french

每次,它都可以在我的 mac 上运行,但不能在我的服务器上运行,我会收到以下错误:

Internal Server Error: /mj/charts/mplimage.png
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/exception.py", line 35, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/base.py", line 128, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/base.py", line 126, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/root/src/jm/majority_judgment/views.py", line 39, in mplimage
    canvas.print_png(response)
  File "/usr/local/lib/python3.6/dist-packages/matplotlib/backends/backend_agg.py", line 526, in print_png
    with cbook.open_file_cm(filename_or_obj, "wb") as fh:
  File "/usr/lib/python3.6/contextlib.py", line 81, in __enter__
    return next(self.gen)
  File "/usr/local/lib/python3.6/dist-packages/matplotlib/cbook/__init__.py", line 624, in open_file_cm
    fh, opened = to_filehandle(path_or_file, mode, True, encoding)
  File "/usr/local/lib/python3.6/dist-packages/matplotlib/cbook/__init__.py", line 615, in to_filehandle
    raise ValueError('fname must be a PathLike or file handle')
ValueError: fname must be a PathLike or file handle
[28/Mar/2018 19:09:11] "GET /mj/charts/mplimage.png HTTP/1.1" 500 82804

这是一个最小的 sn-p:

def mplimage(request):
    f = matplotlib.figure.Figure()
    canvas = FigureCanvasAgg(f)
    response = HttpResponse(content_type='image/png')
    canvas.print_png(response)
    plt.close(f)
    return response

我尝试过更新matplotlib、django等,但是什么都没做……

【问题讨论】:

  • 使用 print_jpg 和 'image/jpg' 作为 Content-Type,它应该可以按预期工作。

标签: python django matplotlib


【解决方案1】:

目前,matplotlib 的编写函数 require the seek ducktype 在文件中使用响应。您可以写入缓冲区,如下所示:

import io

def mplimage(request):
    f = matplotlib.figure.Figure()

    # Code that sets up figure goes here; in the question, that's ...
    FigureCanvasAgg(f)

    buf = io.BytesIO()
    plt.savefig(buf, format='png')
    plt.close(f)
    response = HttpResponse(buf.getvalue(), content_type='image/png')
    return response

【讨论】:

    【解决方案2】:

    您可以将响应替换为缓冲区,然后将缓冲区添加到响应中。这将为 canvas.print_png() 提供一个适当的对象,并将代码更改保持在最低限度。

    def mplimage(request):
        f = matplotlib.figure.Figure()
        buf = io.BytesIO()
        canvas = FigureCanvasAgg(f)
        canvas.print_png(buf)
        response=HttpResponse(buf.getvalue(),content_type='image/png')
        # if required clear the figure for reuse 
        f.clear()
        # I recommend to add Content-Length for Django
        response['Content-Length'] = str(len(response.content))
        #
        return response
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 2013-08-20
      • 2013-10-11
      • 2013-01-07
      • 2017-03-19
      • 1970-01-01
      • 2016-02-18
      相关资源
      最近更新 更多