Skip to content

Commit

Permalink
Add a completion visualization
Browse files Browse the repository at this point in the history
  • Loading branch information
matejak committed Jun 16, 2023
1 parent 0d21097 commit e72e942
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 4 deletions.
64 changes: 64 additions & 0 deletions estimage/visualize/completion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import typing
import datetime

import numpy as np

from . import utils
from .. import utilities


class MPLCompletionPlot:
width = 2

def __init__(self, todo_estimation, perweek_velocity_mean_std):
dom, pdf = todo_estimation.divide_by_gauss_pdf(200, * perweek_velocity_mean_std)
self.distribution = utilities.get_random_variable(dom, pdf)
DAYS_IN_WEEK = 7
lower_bound = self.distribution.ppf(0.02)
upper_bound = self.distribution.ppf(0.98)
self.dom = np.arange(
int(np.floor(lower_bound * DAYS_IN_WEEK)),
int(np.ceil(upper_bound * DAYS_IN_WEEK)) + 1)
self.probs = self.distribution.cdf(self.dom / DAYS_IN_WEEK)
self.probs -= self.probs[0]
self.probs /= self.probs[-1]
self.probs *= 100

def _calculate_plan_wrt_day(self, ax, start):
ax.plot(self.dom, self.probs, color="green",
linewidth=self.width, label="prob of completion")
utils.x_axis_weeks_and_months(ax, start, start + utils.ONE_DAY * self.dom[-1])

def get_figure(self):
plt = utils.get_standard_pyplot()

fig, ax = plt.subplots()
ax.grid(True)

self._calculate_plan_wrt_day(ax, datetime.datetime.today())
ax.legend(loc="upper left")

ax.set_ylabel("percents")

return fig

def get_small_figure(self):
plt = utils.get_standard_pyplot()

fig, ax = plt.subplots()

self._prepare_plots()
self._plot_prepared_arrays(ax)
self._show_plan(ax)
self._show_today(ax)

ax.set_axis_off()
fig.subplots_adjust(0, 0, 1, 1)

return fig

def plot_stuff(self):
plt = utils.get_standard_pyplot()
self.get_figure()

plt.show()
6 changes: 3 additions & 3 deletions estimage/visualize/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ def x_axis_weeks_and_months(ax, start, end):
ax.set_xlabel("time / weeks")


def set_week_ticks_to_mondays(ticks, start, end):
week_index = 0
def set_week_ticks_to_mondays(ticks, start, end, week_index_start=0):
week_index = week_index_start
if start.weekday != 0:
week_index = 1
week_index = week_index_start + 1
for day in range((end - start).days + 1):
if (start + day * ONE_DAY).weekday() == 0:
ticks[day] = str(week_index)
Expand Down
35 changes: 34 additions & 1 deletion estimage/webapp/vis/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@

import flask
import flask_login
import numpy as np

from . import bp
from .. import web_utils
from ... import utilities
from ... import simpledata as webdata
from ... import history
from ...visualize import utils, velocity, burndown, pert
from ...visualize import utils, velocity, burndown, pert, completion

import matplotlib

Expand Down Expand Up @@ -52,6 +53,38 @@ def get_pert_in_figure(estimation, task_name):
return fig


@bp.route('/completion.svg')
@flask_login.login_required
def visualize_completion():
user = flask_login.current_user
user_id = user.get_id()
all_events = webdata.EventManager()
all_events.load()

all_targets_by_id, model = web_utils.get_all_tasks_by_id_and_user_model("retro", user_id)
all_targets = list(all_targets_by_id.values())
targets_tree_without_duplicates = utilities.reduce_subsets_from_sets([t for t in all_targets if t.tier == 0])
model = web_utils.get_user_model(user_id, targets_tree_without_duplicates)
todo = model.remaining_point_estimate

start, end = flask.current_app.config["RETROSPECTIVE_PERIOD"]
aggregation = history.Aggregation.from_targets(targets_tree_without_duplicates, start, end)
aggregation.process_event_manager(all_events)

velocity_array = aggregation.get_velocity_array()
velocity_array = velocity_array[velocity_array > 0] * 7
velocity_mean = velocity_array.mean()
velocity_array = np.convolve(velocity_array, np.ones(7) / 7, "same")
velocity_stdev = velocity_array.var()**0.5

matplotlib.use("svg")
print(f"{velocity_mean=}, {velocity_stdev=}")
print(f"{velocity_array=}")
fig = completion.MPLCompletionPlot(todo, (velocity_mean, velocity_stdev)).get_figure()
fig.set_size_inches(* NORMAL_FIGURE_SIZE)
return send_figure_as_svg(fig, "completion.svg")


@bp.route('/<epic_name>-velocity.svg')
@flask_login.login_required
def visualize_velocity(epic_name):
Expand Down

0 comments on commit e72e942

Please sign in to comment.