首页 > 解决方案 > Django - save AxesSubplot via seaborn to django models.ImageField

问题描述

I'm trying to save graph from seaborn module as ImageField to django model.

models.py

class HeatmapFiles(models.Model):
    username = models.ForeignKey(
        'CustomUser',
        verbose_name='Username',
        on_delete=models.CASCADE,
        blank=False
    )
    heatmap = models.ImageField(
        verbose_name='Heatmap',
        blank=False
    )

I've tried to save via ImageFile:

example_file.py

import io
import seaborn as sns
import matplotlib.pyplot as plt
from django.core.files.images import ImageFile

sns.set()
flights_long = sns.load_dataset("flights")
flights = flights_long.pivot("month", "year", "passengers")
f, ax = plt.subplots(figsize=(9, 6))
new = sns.heatmap(flights, annot=True, fmt="d", linewidths=.5, ax=ax)

figure = io.BytesIO()
new.get_figure().savefig(figure, format='png')
image_file = ImageFile(figure.getvalue())

and image_file objects returns None here:

<ImageFile: None>

I can save it, but that doesn't make sense. How to save "new" heatmap object as django model?

UPD: after new.get_figure().savefig(figure, format='png') figure.getvalue() actually HAS data "b'\x89PNG\r\n\x1a\n\x00\x00...." inside.

标签: pythondjangoseaborn

解决方案


It seems you're defining figure as empty bytesIO and put that in image_file = ImageFile(...), so image_file returns None. Besides, new.get_figure().savefig(...) save png file separately.

To save "new" heapmap object as django model.

  1. new.get_figure().savefig save file as you like.

  2. Using that file path in models.ImageField, then a file will be uploaded to django.

Ps: you need () as get_figure(), I think.


推荐阅读