Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #749 - Use streamlit to display graphs in sim plotter #793

Merged
merged 32 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4ac985f
First draft/initial commit.
calina-c Mar 14, 2024
1bf99e2
Add streamlit in setup.py.
calina-c Mar 14, 2024
79c25d7
Merge branch 'main' into streamlit-sim
calina-c Mar 14, 2024
f125719
Fix some linter issues.
calina-c Mar 14, 2024
899d85e
Fix mypy issues.
calina-c Mar 14, 2024
e7fc7d8
Add UX shortcut for streamlit.
calina-c Mar 15, 2024
e86f319
Merge branch 'main' into streamlit-sim
calina-c Mar 15, 2024
7065213
Fix entrpoint conditions.
calina-c Mar 18, 2024
408ab26
Merge branch 'main' into streamlit-sim
calina-c Mar 18, 2024
e7588eb
Merge branch 'main' into streamlit-sim
calina-c Mar 18, 2024
834819b
Convert first line chart.
calina-c Mar 19, 2024
7fa506c
Convert trader profit vs time figure.
calina-c Mar 19, 2024
9ae219e
Convert accuracy plot.
calina-c Mar 19, 2024
04d425b
Grid adjustments.
calina-c Mar 20, 2024
27dbeaf
Merge branch 'main' into streamlit-sim
calina-c Mar 20, 2024
24e51cd
Finish converting scatter plots.
calina-c Mar 20, 2024
ff88e76
Convert precision vs recall chart.
calina-c Mar 20, 2024
663e692
Fix previous merge conflict resolution.
calina-c Mar 20, 2024
cde3f9d
Convert varimps chart.
calina-c Mar 21, 2024
fbd5ab0
Convert contour response.
calina-c Mar 22, 2024
deac2b3
Replace single var plot.
calina-c Mar 25, 2024
2cc991a
Remove former figures from plotters.
calina-c Mar 25, 2024
5ec449a
Linter fixes.
calina-c Mar 25, 2024
950b026
Merge branch 'main' into streamlit-sim
calina-c Mar 25, 2024
0ab6cc8
Fix tests.
calina-c Mar 25, 2024
4967164
Prototype for P/C streamlit plotting.
calina-c Mar 26, 2024
7d2a279
Fixes and corner cases for streamlit sim display.
calina-c Mar 27, 2024
058aaa5
Merge branch 'main' into streamlit-sim
calina-c Mar 27, 2024
e055aef
Linter fixes after merge and P/C architecture fix.
calina-c Mar 27, 2024
312c2c5
Add scaffolding for multisim id.
calina-c Mar 27, 2024
3414c81
Add empty sim state folder to git.
calina-c Mar 27, 2024
7bbb512
Add instructions to readme.
calina-c Mar 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions pdr_backend/cli/cli_module.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import logging
import os
import subprocess
import sys

from enforce_typing import enforce_types
Expand All @@ -10,12 +11,11 @@
get_predictoors_info_main,
get_traction_info_main,
)
from pdr_backend.cli.cli_arguments import (
do_help_long,
get_arg_parser,
print_args,
)
from pdr_backend.cli.cli_arguments import do_help_long, get_arg_parser, print_args
from pdr_backend.deployer.deployer import main as deployer_main
from pdr_backend.dfbuyer.dfbuyer_agent import DFBuyerAgent
from pdr_backend.lake.etl import ETL
from pdr_backend.lake.gql_data_factory import GQLDataFactory
from pdr_backend.lake.ohlcv_data_factory import OhlcvDataFactory
from pdr_backend.payout.payout import do_ocean_payout, do_rose_payout
from pdr_backend.ppss.ppss import PPSS
Expand All @@ -25,13 +25,10 @@
from pdr_backend.trader.approach1.trader_agent1 import TraderAgent1
from pdr_backend.trader.approach2.trader_agent2 import TraderAgent2
from pdr_backend.trueval.trueval_agent import TruevalAgent
from pdr_backend.util.topup import topup_main
from pdr_backend.util.core_accounts import fund_accounts_with_OCEAN
from pdr_backend.util.currency_types import Eth
from pdr_backend.util.web3_accounts import create_accounts, view_accounts, fund_accounts
from pdr_backend.lake.gql_data_factory import GQLDataFactory
from pdr_backend.lake.etl import ETL
from pdr_backend.deployer.deployer import main as deployer_main
from pdr_backend.util.topup import topup_main
from pdr_backend.util.web3_accounts import create_accounts, fund_accounts, view_accounts

logger = logging.getLogger("cli")

Expand All @@ -46,6 +43,11 @@ def _do_main():
if func is None:
do_help_long(1)

if sys.argv[1] == "sim" and sys.argv[0] != "streamlit_entrypoint.py":
streamlit_args = ["streamlit", "run", "streamlit_entrypoint.py"] + sys.argv[1:]
subprocess.run(streamlit_args, check=False)
return

parser = get_arg_parser(func_name)
args, nested_args = parser.parse_known_args()
print_args(args)
Expand Down
90 changes: 57 additions & 33 deletions pdr_backend/sim/sim_plotter.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from typing import List

from enforce_typing import enforce_types
from matplotlib import gridspec
import matplotlib.pyplot as plt
import numpy as np
import streamlit
from enforce_typing import enforce_types
from numpy.random import random

from pdr_backend.aimodel.aimodel_plotdata import AimodelPlotdata
Expand All @@ -15,6 +15,9 @@
from pdr_backend.sim.sim_state import SimState
from pdr_backend.util.constants import FONTSIZE

streamlit.set_page_config(layout="wide")


HEIGHT = 7.5
WIDTH = int(HEIGHT * 3.2)

Expand All @@ -31,28 +34,33 @@ def __init__(
self.st = st
self.ppss = ppss

plt.close("all")

# so labels are above lines. Must be before figure()
plt.rcParams["axes.axisbelow"] = False

# figure, subplots
fig = plt.figure()
self.fig = fig

gs = gridspec.GridSpec(2, 6, width_ratios=[5, 1, 2, 0.6, 2, 3])

self.ax_pdr_profit_vs_time = fig.add_subplot(gs[0, 0])
self.ax_trader_profit_vs_time = fig.add_subplot(gs[1, 0])

self.ax_pdr_profit_vs_ptrue = fig.add_subplot(gs[0, 1])
self.ax_trader_profit_vs_ptrue = fig.add_subplot(gs[1, 1])

self.ax_accuracy_vs_time = fig.add_subplot(gs[0, 2])
self.ax_f1_precision_recall_vs_time = fig.add_subplot(gs[1, 2])

# col 3 is empty, for overflow of aimodel_varimps's y-axis labels
self.ax_aimodel_varimps = fig.add_subplot(gs[:, 4])

self.ax_aimodel_response = fig.add_subplot(gs[:, 5])
c1, c2, c3 = streamlit.columns((1, 2, 1))
c11, c12 = c1.container(), c1.container()
c31, c32 = c3.container(), c3.container()
c4, c5 = streamlit.columns((1, 1))

self.canvas = {
"pdr_profit_vs_time": c11.empty(),
"trader_profit_vs_time": c12.empty(),
"accuracy_vs_time": c2.empty(),
"pdr_profit_vs_ptrue": c31.empty(),
"trader_profit_vs_ptrue": c32.empty(),
"aimodel_varimps": c4.empty(),
"aimodel_response": c5.empty(),
"f1_precision_recall_vs_time": streamlit.empty(),
}

idiom-bytes marked this conversation as resolved.
Show resolved Hide resolved
self.figs = {}

for k, _ in self.canvas.items():
fig, ax = plt.subplots()
self.figs[k] = fig
setattr(self, f"ax_{k}", ax)
idiom-bytes marked this conversation as resolved.
Show resolved Hide resolved

# attributes to help update plots' state quickly
self.N: int = 0
Expand All @@ -61,10 +69,6 @@ def __init__(

self.plotted_before: bool = False

# push plot to screen
plt.ion()
plt.show()

# pylint: disable=too-many-statements
@enforce_types
def make_plot(self, aimodel_plotdata: AimodelPlotdata):
Expand All @@ -90,12 +94,13 @@ def make_plot(self, aimodel_plotdata: AimodelPlotdata):
self._plot_aimodel_response(aimodel_plotdata)

# final pieces
self.fig.set_size_inches(WIDTH, HEIGHT)
self.fig.tight_layout(pad=0.5, h_pad=1.0, w_pad=1.0)
plt.subplots_adjust(wspace=0.3)
# plt.subplots_adjust(wspace=0.3)
plt.pause(0.001)
self.plotted_before = True

plt.ion()
plt.show()

@property
def next_x(self) -> List[float]:
return _slice(self.x, self.N_done, self.N)
Expand All @@ -114,11 +119,13 @@ def _plot_pdr_profit_vs_time(self):
ax.plot(self.next_hx, [0, 0], c="0.2", ls="--", lw=1)
s = f"Predictoor profit vs time. Current:{y00[-1]:.2f} OCEAN"
_set_title(ax, s)

self.canvas["pdr_profit_vs_time"].pyplot(self.figs["pdr_profit_vs_time"])

if not self.plotted_before:
ax.set_ylabel("predictoor profit (OCEAN)", fontsize=FONTSIZE)
ax.set_xlabel("time", fontsize=FONTSIZE)
_ylabel_on_right(ax)
ax.margins(0.005, 0.05)

@enforce_types
def _plot_trader_profit_vs_time(self):
Expand All @@ -128,6 +135,8 @@ def _plot_trader_profit_vs_time(self):
ax.plot(self.next_x, next_y10, c="b")
ax.plot(self.next_hx, [0, 0], c="0.2", ls="--", lw=1)
_set_title(ax, f"Trader profit vs time. Current: ${y10[-1]:.2f}")

self.canvas["trader_profit_vs_time"].pyplot(self.figs["trader_profit_vs_time"])
if not self.plotted_before:
ax.set_xlabel("time", fontsize=FONTSIZE)
ax.set_ylabel("trader profit (USD)", fontsize=FONTSIZE)
Expand All @@ -149,6 +158,8 @@ def _plot_accuracy_vs_time(self):
s = f"accuracy = {clm.acc_ests[-1]*100:.2f}% "
s += f"[{clm.acc_ls[-1]*100:.2f}%, {clm.acc_us[-1]*100:.2f}%]"
_set_title(ax, s)

self.canvas["accuracy_vs_time"].pyplot(self.figs["accuracy_vs_time"])
if not self.plotted_before:
ax.set_xlabel("time", fontsize=FONTSIZE)
ax.set_ylabel("% correct [lower, upper bound]", fontsize=FONTSIZE)
Expand All @@ -173,6 +184,9 @@ def _plot_f1_precision_recall_vs_time(self):
s += f" [recall={clm.recalls[-1]:.4f}"
s += f", precision={clm.precisions[-1]:.4f}]"
_set_title(ax, s)
self.canvas["f1_precision_recall_vs_time"].pyplot(
self.figs["f1_precision_recall_vs_time"]
)
if not self.plotted_before:
ax.set_xlabel("time", fontsize=FONTSIZE)
ax.set_ylabel("f1 [recall, precision]", fontsize=FONTSIZE)
Expand All @@ -195,6 +209,8 @@ def _plot_pdr_profit_vs_ptrue(self):
s = f"pdr profit dist. avg={avg:.2f} OCEAN"
_set_title(ax, s)
ax.plot([0.5, 0.5], [mnp, mxp], c="0.2", ls="-", lw=1)

self.canvas["pdr_profit_vs_ptrue"].pyplot(self.figs["pdr_profit_vs_ptrue"])
if not self.plotted_before:
ax.plot([0.0, 1.0], [0, 0], c="0.2", ls="--", lw=1)
_set_xlabel(ax, "prob(up)")
Expand All @@ -218,6 +234,10 @@ def _plot_trader_profit_vs_ptrue(self):

_set_title(ax, s)
ax.plot([0.5, 0.5], [mnp, mxp], c="0.2", ls="-", lw=1)

self.canvas["trader_profit_vs_ptrue"].pyplot(
self.figs["trader_profit_vs_ptrue"]
)
if not self.plotted_before:
ax.plot([0.0, 1.0], [0, 0], c="0.2", ls="--", lw=1)
_set_xlabel(ax, "prob(up)")
Expand All @@ -227,16 +247,20 @@ def _plot_trader_profit_vs_ptrue(self):

@enforce_types
def _plot_aimodel_varimps(self, d: AimodelPlotdata):
ax = self.ax_aimodel_varimps
ax = self.ax_aimodel_varimps # type: ignore[attr-defined]
imps_tups = d.model.importance_per_var(include_stddev=True)
plot_aimodel_varimps(d.colnames, imps_tups, (self.fig, ax))
plot_aimodel_varimps(d.colnames, imps_tups, (self.figs["aimodel_varimps"], ax))

self.canvas["aimodel_varimps"].pyplot(self.figs["aimodel_varimps"])
if not self.plotted_before:
ax.margins(0.01, 0.01)

@enforce_types
def _plot_aimodel_response(self, d: AimodelPlotdata):
ax = self.ax_aimodel_response
plot_aimodel_response(d, (self.fig, ax))
ax = self.ax_aimodel_response # type: ignore[attr-defined]
plot_aimodel_response(d, (self.figs["aimodel_varimps"], ax))

self.canvas["aimodel_response"].pyplot(self.figs["aimodel_response"])
if not self.plotted_before:
ax.margins(0.01, 0.01)

Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"types-requests==2.31.0.20240311",
"web3==6.15.1",
"sapphire.py==0.2.2",
"streamlit==1.32.1",
"ocean-contracts==2.0.0a14", # install this last
]

Expand Down
6 changes: 6 additions & 0 deletions streamlit_entrypoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env python

from pdr_backend.cli import cli_module

if __name__ == "__main__":
cli_module._do_main()
Loading