98 lines
2.7 KiB
Python
98 lines
2.7 KiB
Python
import matplotlib.pyplot as plt
|
|
import matplotlib, io
|
|
import plotly.express as px
|
|
import plotly
|
|
from datetime import datetime
|
|
|
|
|
|
def generate_table(headers, data, title="", bg="skyblue", border="steelblue"):
|
|
timestamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
|
|
|
|
font = {"family": "monospace", "weight": "normal", "size": 12}
|
|
|
|
matplotlib.rc("font", **font)
|
|
|
|
title_text = title
|
|
footer_text = timestamp
|
|
fig_background_color = bg
|
|
fig_border = border
|
|
|
|
column_headers = headers
|
|
|
|
if data:
|
|
cell_text = []
|
|
for row in data:
|
|
cell_text.append([x for x in row])
|
|
else:
|
|
cell_text = [["No Data"] + ["" for x in range(len(headers) - 1)]]
|
|
|
|
# Create the figure. Setting a small pad on tight_layout
|
|
# seems to better regulate white space. Sometimes experimenting
|
|
# with an explicit figsize here can produce better outcome.
|
|
|
|
dpi = 160
|
|
# image_height = (( 0.5 + ( 0.4125 * ( len(data) + 1) ) ) * dpi)
|
|
image_height = 100 + (67 * (len(data) + 1))
|
|
image_width = 6 * dpi
|
|
|
|
plt.figure(
|
|
linewidth=2,
|
|
edgecolor=fig_border,
|
|
facecolor=fig_background_color,
|
|
tight_layout={"pad": 1},
|
|
dpi=dpi,
|
|
figsize=(image_width / dpi, image_height / dpi),
|
|
)
|
|
|
|
# Add a table at the bottom of the axes
|
|
the_table = plt.table(
|
|
cellText=cell_text, colLabels=column_headers, loc="upper center"
|
|
)
|
|
|
|
# Scaling is the only influence we have over top and bottom cell padding.
|
|
# Make the rows taller (i.e., make cell y scale larger).
|
|
the_table.scale(1, 2)
|
|
|
|
# Hide axes
|
|
ax = plt.gca()
|
|
ax.get_xaxis().set_visible(False)
|
|
ax.get_yaxis().set_visible(False)
|
|
|
|
# Hide axes border
|
|
plt.box(on=None)
|
|
|
|
# Add title
|
|
plt.suptitle(title_text, x=0.5, y=((image_height - 15) / image_height))
|
|
|
|
# Add footer
|
|
plt.figtext(
|
|
((image_width - 15) / image_width),
|
|
1 - ((image_height - 15) / image_height),
|
|
footer_text,
|
|
horizontalalignment="right",
|
|
size=12,
|
|
weight="light",
|
|
)
|
|
|
|
# Force the figure to update, so backends center objects correctly within the figure.
|
|
# Without plt.draw() here, the title will center on the axes and not the figure.
|
|
plt.draw()
|
|
|
|
# Create image. plt.savefig ignores figure edge and face colors, so map them.
|
|
image_buffer = io.BytesIO()
|
|
plt.savefig(image_buffer, format="png")
|
|
image_buffer.seek(0)
|
|
return image_buffer
|
|
|
|
|
|
def generate_chart(ticker, history):
|
|
fig = px.line(
|
|
history,
|
|
x=history.index,
|
|
y="Open",
|
|
title="{} Stock Prices".format(ticker),
|
|
labels={"Open": "Price Per Share"},
|
|
)
|
|
|
|
img_bytes = plotly.io.to_image(fig, format="png")
|
|
return io.BytesIO(img_bytes)
|