简体   繁体   中英

Matplotlib Flask Heroku Application Error

I've gone over this problem for ages. I successfully deployed a website with flask that contains a graph, .png image I created using matplotlib.

However, I wanted to include the matplotlib code in my flask application, so that every time the screen is refreshed, the graph changes since it's using randomly generated data.

I can deploy my app successfully with matplotlib, but I keep getting "Application Error" repeatedly when I check my website. It works locally on my computer without any issues though.

Here are the steps I followed in the command terminal:

  1. Create a virtual environment
  2. pip install datetime, pandas, matplotlib, lorem, gunicorn
  3. easy_install -U distribute
  4. pip freeze > requirements.txt
  5. Created and tested different Procfile's to see if anything would work.

    web: gunicorn gettingstarted.wsgi --log-file -

    web: gunicorn --bind 0.0.0.0:$PORT app:app

    web: gunicorn -b :$PORT app:app

6.

 git init
heroku git:remote -a name-of-app
git add .
git commit -am "random text message"
git push heroku master

It's deployed, but keeps getting application error. If I don't include matplotlib, it works fine.

Here is my code for the app.py

from flask import Flask
from flask import Flask, render_template, url_for, redirect

from datetime import datetime as dt
import numpy as np
import matplotlib.pyplot as plt
import lorem

app = Flask(__name__)

data = {["AAPL", "MSFT", "GOOG"][i]: np.random.randint(100, 400, 12) for i in range(3)}
data
plt.figure(figsize=(8, 5))

plt.plot(data["AAPL"])
plt.plot(data["MSFT"])
plt.plot(data["GOOG"])

plt.title("APPL v MSFT v GOOG Stock 2019", fontsize= 20)
plt.xlabel("Months", fontsize=20)
plt.ylabel("Price in $", fontsize = 20)
plt.legend(list(data.keys())[:3], fontsize=14, loc="best")
path = "C:/Users/Michael/Desktop/WEB4/flaskdeploy/static/"
plt.savefig(path + "stock.png", dpi = 300, bbox_inches = "tight");
#plt.show();
plt.tight_layout()

date = dt.now().strftime("%Y/%m/%d")
timeNow = dt.now().strftime("%H:%M:%S")


text = lorem.text()[:100]

@app.route("/")
def index():

    return render_template("home.html", text = text, date=date, timeNow=timeNow)


if __name__ == "__main__":
    app.run(debug=True)

My requirements.txt file. Any help would be greatly appreciated. Thanks!

certifi==2018.11.29
Click==7.0
cycler==0.10.0
DateTime==4.3
Flask==1.0.2
gunicorn==19.9.0
itsdangerous==1.1.0
Jinja2==2.10
kiwisolver==1.0.1
lorem==0.1.1
MarkupSafe==1.1.0
matplotlib==3.0.2
numpy==1.15.4
pandas==0.23.4
pyparsing==2.3.0
python-dateutil==2.7.5
pytz==2018.7
six==1.12.0
Werkzeug==0.14.1
wincertstore==0.2
zope.interface==4.6.0

Firstly, if you want Flask to generate new random data every time the page is refreshed, then you should build that data within def index() . Currently your data and plt objects are only built when the Flask server initialises and wakes up.

Secondly your plot data is being saved to a hard coded path on your local C: drive - that won't work from the Heroku hosting environment!
Heroku uses an 'ephemeral' file system that will reset back to its original state every time the dyno is restarted. You can create temporary files (such as an exported plot) but they will disappear as soon as your app sleeps or restarts.

I'd recommend creating a "tmp" folder in your project (you'll need to create a simple static file in there so it isn't an empty folder) and then export your plot there, eg /tmp/stock.png , and update your template accordingly...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM