Отображение изображения matplotlib на HTML-странице с помощью Django

У меня есть генератор wordcloud, который я работаю в записной книжке Jupyter. Я хотел бы создать для него интерфейс, чтобы вы могли вставить текст в текстовое поле, нажать «Отправить», и он отобразит wordcloud. В основном то, что сделал этот парень здесь.

Мне нужна помощь в изменении моего кода, чтобы вместо отображения wordcloud в блокноте Jupyter он отображал изображение wordcloud на HTML-странице. Я использую Django для создания интерфейса.

Это код, который у меня есть, который генерирует изображение моего wordcloud в моем блокноте Jupyter.

from wordcloud import WordCloud
from PIL import Image
import matplotlib.pyplot as plt
import nltk
# sun only once -> nltk.download('punkt')
#nltk.download('wordnet') -> only do this once
from nltk.stem.porter import PorterStemmer
from nltk.stem import WordNetLemmatizer
ps = PorterStemmer()
wnl = WordNetLemmatizer()

def stem(string):    
    stemstring = ""
    nltk_tokens = nltk.word_tokenize(string)
    for word in nltk_tokens: 
        if word in dontstem:
            p = word
        elif word == 'printing':
            p = 'print'
        elif word == 'e-mailing':
            p = 'email'
        elif word == 'e-mails':
            p = 'email'
        elif word == 'e-mail':
            p = 'email'
        elif word == 'installation':
            p = 'install'
        #If the lemmatized word ends in a 'e' then lemmatize instead of stem as stem cuts the 'e'.    
        elif wnl.lemmatize(word).endswith('e'):
            p = wnl.lemmatize(word)
        elif wnl.lemmatize(word).endswith('y'):
            p = wnl.lemmatize(word)
        elif wnl.lemmatize(word).endswith('er'):
            p = wnl.lemmatize(word)
        elif wnl.lemmatize(word).endswith('ing'):
            p = wnl.lemmatize(word)
        else:
            p = ps.stem(word)
        stemstring += p + ' '
    return stemstring

#We use a srt.split() to only count whole words as we don't want to count words inside words. This can happen below. 
def count_substring(string,sub_string):
    count=0
    for word in string.split():
        if word == sub_string:      
            count+=1
    return(count)  

#As we have a phrase which can be made up of two words we use this counting method as it is unlikely that the phrase is contained in another word.
def count_substring_phrases(string,sub_string):
    count=0
    for i in range(len(string)-len(sub_string)+1):
        if (string[i:i+len(sub_string)] == sub_string ):      
            count+=1
    return(count) 

#The function for counting all the words
def countWords(string, phrases, stopWords, dostem):
    newList = {}
    for p in phrases:
        if count_substring_phrases(string,p) > 0:
            newList[p] = count_substring_phrases(string,p)
            string = string.replace(p,'')
        else:
            pass

    if dostem == True:    
        string = stem(string)

    for word in string.split():
        if word in stopWords:
                pass
        #Hack to exclude any word under 4 characters.    
        elif len(word) < 2:
            pass
        else:
            count_substring(string,word)
            newList[word] = count_substring(string,word)

    return(newList) 

MyData= dict(countWords(text, phrases, stopWords, True))
wc = WordCloud(scale=10, max_words=100).generate_from_frequencies(MyData)

plt.figure(figsize=(32,18))
plt.imshow(wc, interpolation = "bilinear", aspect='auto')
plt.show()

Вот мой файл views.py. Как видите, я могу получить значение из поля формы и отправить его обратно на страницу. Теперь мне нужно получить значение из поля формы, запустить его через функцию wordcloud, сгенерировать изображение wordcloud, а затем отправить его обратно на страницу, чтобы я мог его отобразить.

from django.shortcuts import render
from wordcloudgen.forms import CharForm
from wordcloudgen.wordcloud import *

def cloud_gen(request):
    if request.method == 'POST':
        form = CharForm(request.POST)
        if form.is_valid():
            text = form.cleaned_data['post']
            phrases = ''
            stopWords = ''


            args = {'form':form, 'text':text}
            return render(request, 'wordcloudgen/cloud_gen.html', args)
    else:
        form = CharForm()
        return render(request, 'wordcloudgen/cloud_gen.html', {'form':form})

Я бы подумал, что мне нужно что-то изменить в коде wordcloud здесь:

MyData= dict(countWords(text, phrases, stopWords, True))
wc = WordCloud(scale=10, max_words=100).generate_from_frequencies(MyData)

plt.figure(figsize=(32,18))
plt.imshow(wc, interpolation = "bilinear", aspect='auto')
plt.show()

а затем добавить что-нибудь в представление для вызова функции wordcloud, каким-то образом сохранить изображение, которое оно выводит, а затем передать его в мою переменную args, чтобы я мог вызвать его в шаблоне HTML с чем-то вроде {% image%}.

Примечания: На данный момент некоторые аргументы в функции countWords жестко запрограммированы в пустые строки. Прямо сейчас в форме есть только одно поле ввода, которое будет для текста, когда у меня все будет работать, я затем пойду и добавлю вводы для всех других аргументов и опций, размеров графика для вывода и т. д.

Спасибо

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
2 965
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я понял, что хотел сделать здесь.

Я изменил свой файл Views.py на следующее:

from django.shortcuts import render
from wordcloudgen.forms import CharForm
from wordcloudgen.wordcloud import *

import io
import urllib, base64

def cloud_gen(request):
   if request.method == 'POST':
       form = CharForm(request.POST)
       if form.is_valid():
           text = form.cleaned_data['post']
           phrases = ''
           stopWords = ''

           MyData= dict(countWords(text, phrases, stopWords, True))
           wc = WordCloud(scale=10, max_words=100).generate_from_frequencies(MyData)

           plt.figure(figsize=(32,18))
           plt.imshow(wc, interpolation = "bilinear", aspect='auto')

           fig = plt.gcf()
           buf = io.BytesIO()
           fig.savefig(buf, format='png')
           buf.seek(0)
           string = base64.b64encode(buf.read())

           uri = 'data:image/png;base64,' + urllib.parse.quote(string)

           args = {'form':form, 'text':text, 'image':uri}
           return render(request, 'wordcloudgen/cloud_gen.html', args)
   else:
       form = CharForm()
       return render(request, 'wordcloudgen/cloud_gen.html', {'form':form})

На моей странице шаблона я могу отобразить изображение, используя следующее: <img src = "{{ image }}">

Другие вопросы по теме