I've been struggling to insert a graph/chart into the html. I've tried a basic matplotlib chart (TEST FIG 1) using mpld3 to convert the figure to html. I've also tried to create a graph with mplfinance (TEST FIG 2). All of what I've tried so far has been unsuccessful, going on days now.
First chart I'm wanting to make, I'm trying to pull data for each ticker into a chart that corresponds with the correct ticker's ticker_page.html. Then I tried to make it even more simple, hence (TEST FIG 1)
I'm thinking my problem is really how to link the @app.route correctly. I am not wanting a .png or something static, since later when I understand the connection better I'll make the figures interactive with possible hyperlinks, scrolling features, etc.
For background info on how the app is set up so far, there is a /News page. On the News page there are names in a list. When you click on one of the names it takes you to the /ticker page, which displays the ticker_page.html correctly other than the charts I've tried to insert.
APP.PY:
from flask import Flask, render_template, request
from datetime import datetime
from itertools import groupby
import pipeline
import mpld3
import matplotlib.pyplot as plt
import pandas_datareader
import mplfinance as mpf
app = Flask(__name__)
# Read in the data from the CSV file
CSV_data = 'path'
with open(CSV_data, 'r', encoding='utf-8') as csvfile:
reader = csv.DictReader(csvfile)
articles = [row for row in reader]
# Get the list of unique tickers from the data
tickers = sorted(set(article['Ticker'] for article in articles))
def format_date(date_str):
try:
# Check if date string is in "DD-Mon-YY" format
date_obj = datetime.strptime(date_str, "%d-%b-%y")
except ValueError:
# Check if date string is in "MM/DD/YYYY" format
date_obj = datetime.strptime(date_str, "%m/%d/%Y")
return date_obj.date().strftime("%m-%d-%Y")
def sort_articles(articles):
try:
return sorted(articles, key=lambda x: datetime.strptime(x["Date"], "%m-%d-%Y"), reverse=True)
except (KeyError, ValueError):
print("Houston, we have a problem")
return articles
@app.route('/')
def index():
# Your logic for the home page here
# For example, you can set up a welcome message
welcome_message = "Welcome!"
return render_template('index.html', welcome_message=welcome_message)
@app.route('/news')
def urls():
selected_tickers = request.args.getlist('ticker')
# Filter the articles based on the selected tickers
filtered_articles = [article for article in articles if not selected_tickers or article['Ticker'] in selected_tickers]
# Generate a dictionary to map each ticker to its date, title, and link
ticker_articles = {}
for article in filtered_articles:
ticker = article['Ticker']
if ticker not in ticker_articles:
ticker_articles[ticker] = []
ticker_articles[ticker].append((article['Date'], article['Title'], article['Link']))
# Render the 'urls.html' template with the necessary data
return render_template('urls.html', tickers=tickers, filtered_articles=filtered_articles, ticker_articles=ticker_articles)
#TEST FIG 1
@app.route('/graph/<string:ticker>/')
def graph(ticker):
fig, ax = plt.subplots(ticker)
# Add some data to the plot
ax.plot([1, 2, 3], [4, 5, 6])
# Convert the Matplotlib figure to HTML
html_graph = mpld3.fig_to_html(fig)
return render_template('ticker_page.html', html_graph=html_graph)
#TEST FIG 2
@app.route('/pricegraph/<string:ticker>/')
def generate_price_chart(ticker):
"""Generates a price chart for the given ticker."""
# Get the historical price data for the ticker
df = mpf.DataReader(ticker, period="1d")
# Create a Matplotlib figure
fig = mpf.figure(figsize=(10, 6))
# Add the price chart to the figure
mpf.plot(df, type="candle", style="yahoo", fig=fig, ax=fig.add_subplot(111))
# Convert the Matplotlib figure to HTML
html = mpf.fig_to_html(fig)
return html
@app.route('/ticker/<string:ticker>/')
def ticker_page(ticker):
# Sample data for demonstration purposes
ticker_data = {
'ticker': ticker,
'date': '2023-07-19',
'article_name': 'Sample Article for ' + ticker,
'article_url': 'https://example.com/' + ticker,
#'chart': html_graph
}
# Render the 'ticker_page.html' template with the ticker data
return render_template('ticker_page.html', ticker_data=ticker_data)#, html_graph=html_graph)#, html=html_pipeline)
if __name__ == '__main__':
app.run(debug=True)
TICKER_PAGE.HTML
{% extends 'base.html' %}
{% block content %}
<title>{{ ticker_data.ticker }} Page - TITLE</title>
<head>
</head>
<body>
<div></div>
<div id="data"><h1>{{ ticker_data.ticker }}</h1>
<p>Date: {{ ticker_data.date }}</p>
</div>
<div id="pipeline">
<h2>Pipeline Chart</h2>
<div>
{{html_graph}}
</div>
<div>
<script>
// Get the price chart HTML
var html = "{{ html }}";
// Render the price chart
document.getElementById("pricegraph").innerHTML = html;
</script> </div>
</div>
<div id="news">
<h2>Press Releases</h2>
<p>Sample Article URL:
<a href="{{ ticker_data.article_url }}" target="_blank">{{ ticker_data.article_name }}</a>
</p>
<p>Sample Article: {{ ticker_data.article_name }}</p>
</div>
</div>
</body>
{% endblock %}
I've been struggling to insert a graph/chart into the html. I've tried a basic matplotlib chart (TEST FIG 1) using mpld3 to convert the figure to html. I've also tried to create a graph with mplfinance (TEST FIG 2). All of what I've tried so far has been unsuccessful, going on days now.
I'm thinking my problem is really how to link the @app.route correctly. I am not wanting a .png or something static, since later when I understand the connection better I'll make the figures interactive with possible hyperlinks, scrolling features, etc.
For background info on how the app is set up so far, there is a /News page. On the News page there are names in a list. When you click on one of the names it takes you to the /ticker page, which displays the ticker_page.html correctly other than the charts I've tried to insert.
APP.PY:
from flask import Flask, render_template, request
from datetime import datetime
from itertools import groupby
import pipeline
import mpld3
import matplotlib.pyplot as plt
import pandas_datareader
import mplfinance as mpf
app = Flask(__name__)
# Read in the data from the CSV file
CSV_data = 'path'
with open(CSV_data, 'r', encoding='utf-8') as csvfile:
reader = csv.DictReader(csvfile)
articles = [row for row in reader]
# Get the list of unique tickers from the data
tickers = sorted(set(article['Ticker'] for article in articles))
def format_date(date_str):
try:
# Check if date string is in "DD-Mon-YY" format
date_obj = datetime.strptime(date_str, "%d-%b-%y")
except ValueError:
# Check if date string is in "MM/DD/YYYY" format
date_obj = datetime.strptime(date_str, "%m/%d/%Y")
return date_obj.date().strftime("%m-%d-%Y")
def sort_articles(articles):
try:
return sorted(articles, key=lambda x: datetime.strptime(x["Date"], "%m-%d-%Y"), reverse=True)
except (KeyError, ValueError):
print("Houston, we have a problem")
return articles
@app.route('/')
def index():
# Your logic for the home page here
# For example, you can set up a welcome message
welcome_message = "Welcome!"
return render_template('index.html', welcome_message=welcome_message)
@app.route('/news')
def urls():
selected_tickers = request.args.getlist('ticker')
# Filter the articles based on the selected tickers
filtered_articles = [article for article in articles if not selected_tickers or article['Ticker'] in selected_tickers]
# Generate a dictionary to map each ticker to its date, title, and link
ticker_articles = {}
for article in filtered_articles:
ticker = article['Ticker']
if ticker not in ticker_articles:
ticker_articles[ticker] = []
ticker_articles[ticker].append((article['Date'], article['Title'], article['Link']))
# Render the 'urls.html' template with the necessary data
return render_template('urls.html', tickers=tickers, filtered_articles=filtered_articles, ticker_articles=ticker_articles)
#TEST FIG 1
@app.route('/graph/<string:ticker>/')
def graph(ticker):
fig, ax = plt.subplots(ticker)
# Add some data to the plot
ax.plot([1, 2, 3], [4, 5, 6])
# Convert the Matplotlib figure to HTML
html_graph = mpld3.fig_to_html(fig)
return render_template('ticker_page.html', html_graph=html_graph)
#TEST FIG 2
@app.route('/pricegraph/<string:ticker>/')
def generate_price_chart(ticker):
"""Generates a price chart for the given ticker."""
# Get the historical price data for the ticker
df = mpf.DataReader(ticker, period="1d")
# Create a Matplotlib figure
fig = mpf.figure(figsize=(10, 6))
# Add the price chart to the figure
mpf.plot(df, type="candle", style="yahoo", fig=fig, ax=fig.add_subplot(111))
# Convert the Matplotlib figure to HTML
html = mpf.fig_to_html(fig)
return html
@app.route('/ticker/<string:ticker>/')
def ticker_page(ticker):
# Sample data for demonstration purposes
ticker_data = {
'ticker': ticker,
'date': '2023-07-19',
'article_name': 'Sample Article for ' + ticker,
'article_url': 'https://example.com/' + ticker,
#'chart': html_graph
}
# Render the 'ticker_page.html' template with the ticker data
return render_template('ticker_page.html', ticker_data=ticker_data)#, html_graph=html_graph)#, html=html_pipeline)
if __name__ == '__main__':
app.run(debug=True)
TICKER_PAGE.HTML
{% extends 'base.html' %}
{% block content %}
<title>{{ ticker_data.ticker }} Page - TITLE</title>
<head>
</head>
<body>
<div></div>
<div id="data"><h1>{{ ticker_data.ticker }}</h1>
<p>Date: {{ ticker_data.date }}</p>
</div>
<div id="pipeline">
<h2>Pipeline Chart</h2>
<div>
{{html_graph}}
</div>
<div>
<script>
// Get the price chart HTML
var html = "{{ html }}";
// Render the price chart
document.getElementById("pricegraph").innerHTML = html;
</script> </div>
</div>
<div id="news">
<h2>Press Releases</h2>
<p>Sample Article URL:
<a href="{{ ticker_data.article_url }}" target="_blank">{{ ticker_data.article_name }}</a>
</p>
<p>Sample Article: {{ ticker_data.article_name }}</p>
</div>
</div>
</body>
{% endblock %}
I figured out partially what I'm going for, but enough to answer the base of this question. I shouldn't have been using
matplotlib. I should have been usingchart.js. I don't know how to call fromapp.pyyet, but now I've found I can insert the chart directly into the HTML.Link to chart.js docs: https://www.chartjs.org/docs/latest/
ticker_page.html