Files
attentive-neural-processes/src/plot.py
T
2020-02-01 13:09:01 +08:00

116 lines
3.2 KiB
Python

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
import torch
import io
import PIL
from torchvision.transforms import ToTensor
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
eps = 1e-5
def plot_rows(
target_y_rows: pd.DataFrame,
context_y_rows: pd.DataFrame,
pred_y: np.array,
std: np.array,
undo_log=False,
legend=True,
):
"""Plots the predicted mean and variance and the context points.
Args:
target_y_rows
context_y_rows: dataframe with datetime index, and labels
pred_y: An array of shape [B,num_targets,1] that contains the
predicted means of the y values at the target points in target_x.
std: An array of shape [B,num_targets,1] that contains the
predicted std dev of the y values at the target points in target_x.
"""
if undo_log:
target_y_rows = np.exp(target_y_rows) - eps
context_y_rows = np.exp(context_y_rows) - eps
# Plot everything
j = 0
label = "energy(kWh/hh)"
# Start with true data and use it to get ylimits (that way they are constant)
plt.plot(target_y_rows.index, target_y_rows.values, "k:", linewidth=2, label="true")
ylims = plt.ylim()
# plot predictions
plt.plot(target_y_rows.index, pred_y[0], "b", linewidth=2, label="predicted")
plt.fill_between(
target_y_rows.index,
pred_y[0, :, 0] - std[0, :, 0],
pred_y[0, :, 0] + std[0, :, 0],
alpha=0.25,
facecolor="blue",
interpolate=True,
label="uncertainty",
)
# Finally context, we do this with pandas so it will override x ax and make it nice
context_y_rows[label].plot(
style="ko", linewidth=2, label="input data", ax=plt.gca()
)
# Make the plot pretty
plt.grid("off")
plt.ylim(*ylims)
plt.xlabel("Date")
plt.ylabel("Energy (kWh/hh)")
plt.grid(b=None)
if legend:
plt.legend()
def plot_from_loader(
loader, model, i=0, undo_log=False, title="", plot=True, legend=False
):
device = next(model.parameters()).device
data = loader.collate_fn([loader.dataset[i]], sample=False)
data = [d.to(device) for d in data]
context_x, context_y, target_x, target_y = data
x_rows, y_rows = loader.dataset.get_rows(i)
max_num_context = context_x.shape[1]
y_context_rows = y_rows[:max_num_context]
dt = y_context_rows.index[0]
model.eval()
with torch.no_grad():
y_pred, kl, loss_test, y_std = model(context_x, context_y, target_x, target_y)
if plot:
plt.figure()
plt.title(title + f" loss={loss_test: 2.2g} {dt}")
plot_rows(
y_rows,
y_context_rows,
y_pred.detach().cpu().numpy(),
y_std.detach().cpu().numpy(),
undo_log=False,
legend=legend,
)
return loss_test
def plot_from_loader_to_tensor(
*args, **kwargs
):
plot_from_loader(*args, **kwargs)
# Send fig to tensorboard
buf = io.BytesIO()
plt.savefig(buf, format='jpeg')
plt.close()
buf.seek(0)
image = PIL.Image.open(buf)
image = ToTensor()(image)#.unsqueeze(0)
return image