Skip to content

Commit

Permalink
Merge pull request #113 from kurusugawa-computer/feature/stat-per-image
Browse files Browse the repository at this point in the history
Feature/stat per image
  • Loading branch information
yuji38kwmt authored Nov 6, 2019
2 parents 4a666cb + 9a0f6bc commit 001e4f9
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 91 deletions.
70 changes: 35 additions & 35 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion annofabcli/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.13.2'
__version__ = '1.13.3'
15 changes: 8 additions & 7 deletions annofabcli/input_data/put_input_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,25 @@ class PutInputData(AbstractCommandLineInterface):
"""
def put_input_data(self, project_id: str, csv_input_data: CsvInputData,
last_updated_datetime: Optional[str] = None):

request_body: Dict[str, Any] = {'last_updated_datetime': last_updated_datetime}

if is_file_scheme(csv_input_data.input_data_path):
request_body = {
request_body.update({
'input_data_name': csv_input_data.input_data_name,
'sign_required': csv_input_data.sign_required,
}
})
file_path = get_file_scheme_path(csv_input_data.input_data_path)
logger.debug(f"'{file_path}'を入力データとして登録します。")
self.service.wrapper.put_input_data_from_file(project_id, input_data_id=csv_input_data.input_data_id,
file_path=file_path, request_body=request_body)

else:
request_body = {
request_body.update({
'input_data_name': csv_input_data.input_data_name,
'input_data_path': csv_input_data.input_data_path,
'sign_required': csv_input_data.sign_required,
}
if last_updated_datetime is not None:
request_body.update({'last_updated_datetime': last_updated_datetime})
})

self.service.api.put_input_data(project_id, csv_input_data.input_data_id, request_body=request_body)

Expand Down Expand Up @@ -115,7 +116,7 @@ def put_input_data_list(self, project_id: str, input_data_list: List[CsvInputDat

# 入力データを登録
try:
self.put_input_data(project_id, csv_input_data, last_updated_datetime)
self.put_input_data(project_id, csv_input_data, last_updated_datetime=last_updated_datetime)
logger.debug(f"入力データを登録しました。"
f"input_data_id={csv_input_data.input_data_id}, "
f"input_data_name={csv_input_data.input_data_name}")
Expand Down
130 changes: 84 additions & 46 deletions annofabcli/statistics/graph.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import logging
from typing import List, Optional
from typing import Any, Dict, List, Optional # pylint: disable=unused-import

import bokeh
import bokeh.layouts
Expand Down Expand Up @@ -37,7 +37,7 @@ def __init__(self, table: Table, outdir: str):
self.short_project_id = table.project_id[0:8]

@staticmethod
def _create_hover_tool(tool_tip_items: List[str] = None):
def _create_hover_tool(tool_tip_items: List[str] = None) -> HoverTool:
"""
HoverTool用のオブジェクトを生成する。
Returns:
Expand Down Expand Up @@ -70,12 +70,12 @@ def _plot_line_and_circle(fig, x, y, source, username, color):
"""

fig.line(x=x, y=y, source=source, legend=username, line_color=color, line_width=1, muted_alpha=0.2,
fig.line(x=x, y=y, source=source, legend_label=username, line_color=color, line_width=1, muted_alpha=0.2,
muted_color=color)
fig.circle(x=x, y=y, source=source, legend=username, muted_alpha=0.0, muted_color=color, color=color)
fig.circle(x=x, y=y, source=source, legend_label=username, muted_alpha=0.0, muted_color=color, color=color)

@staticmethod
def _set_legend(fig: bokeh.plotting.Figure, hover_tool):
def _set_legend(fig: bokeh.plotting.Figure, hover_tool: HoverTool):
"""
凡例の設定。
Args:
Expand Down Expand Up @@ -170,6 +170,56 @@ def write_アノテーションあたり作業時間(self, task_df: pd.DataFrame
Returns:
"""
def write_cumulative_graph(fig_info_list: List[Dict[str, str]], html_title: str):
"""
累計グラフを出力する。
Args:
fig_info_list:
html_title:
Returns:
"""
figs: List[bokeh.plotting.Figure] = []
for fig_info in fig_info_list:
figs.append(
figure(plot_width=1200, plot_height=600, title=fig_info["title"],
x_axis_label=fig_info["x_axis_label"], y_axis_label=fig_info["y_axis_label"]))

for user_index, user_id in enumerate(first_annotation_user_id_list): # type: ignore
filtered_df = df[df["first_annotation_user_id"] == user_id]
if filtered_df.empty:
logger.debug(f"dataframe is empty. user_id = {user_id}")
continue

# 列が多すぎるとbokehのグラフが表示されないので絞り込む
columns = tooltip_item + [
"cumulative_annotation_count",
"cumulative_input_data_count",
"cumulative_task_count",
"cumulative_annotation_worktime_hour",
"cumulative_inspection_worktime_hour",
"cumulative_acceptance_worktime_hour",
"cumulative_inspection_count",
]

filtered_df = filtered_df[columns]
source = ColumnDataSource(data=filtered_df)
color = self.my_palette[user_index]
username = filtered_df.iloc[0]["first_annotation_username"]

for fig, fig_info in zip(figs, fig_info_list):
self._plot_line_and_circle(fig, x=fig_info["x"], y=fig_info["y"], source=source, username=username,
color=color)

hover_tool = self._create_hover_tool(tooltip_item)
for fig in figs:
self._set_legend(fig, hover_tool)

bokeh.plotting.reset_output()
bokeh.plotting.output_file(f"{self.outdir}/{self.short_project_id}_{html_title}.html", title=html_title)
bokeh.plotting.save(bokeh.layouts.column(figs))

tooltip_item = [
"task_id",
Expand All @@ -182,6 +232,7 @@ def write_アノテーションあたり作業時間(self, task_df: pd.DataFrame
"inspection_worktime_hour",
"acceptance_worktime_hour",
"annotation_count",
"input_data_count",
"inspection_count",
]

Expand All @@ -205,8 +256,8 @@ def write_アノテーションあたり作業時間(self, task_df: pd.DataFrame
# 累計値を計算
df = self.table.create_cumulative_df(task_df)

# グラフの情報
fig_info_list = [
# 横軸が累計のアノテーション数
fig_info_list_annotation_count = [
dict(x="cumulative_annotation_count", y="cumulative_annotation_worktime_hour",
title="アノテーション数と教師付作業時間の累積グラフ", x_axis_label="アノテーション数", y_axis_label="教師付作業時間[hour]"),
dict(x="cumulative_annotation_count", y="cumulative_inspection_worktime_hour",
Expand All @@ -216,42 +267,29 @@ def write_アノテーションあたり作業時間(self, task_df: pd.DataFrame
dict(x="cumulative_annotation_count", y="cumulative_inspection_count", title="アノテーション数と検査コメント数の累積グラフ",
x_axis_label="アノテーション数", y_axis_label="検査コメント数"),
]

figs = []
for fig_info in fig_info_list:
figs.append(
figure(plot_width=1200, plot_height=600, title=fig_info["title"], x_axis_label=fig_info["x_axis_label"],
y_axis_label=fig_info["y_axis_label"]))

for user_index, user_id in enumerate(first_annotation_user_id_list):
filtered_df = df[df["first_annotation_user_id"] == user_id]
if filtered_df.empty:
logger.debug(f"dataframe is empty. user_id = {user_id}")
continue

# 列が多すぎるとbokehのグラフが表示されないので絞り込む
columns = tooltip_item + [
"cumulative_annotation_count",
"cumulative_annotation_worktime_hour",
"cumulative_inspection_worktime_hour",
"cumulative_acceptance_worktime_hour",
"cumulative_inspection_count",
]

filtered_df = filtered_df[columns]
source = ColumnDataSource(data=filtered_df)
color = self.my_palette[user_index]
username = filtered_df.iloc[0]["first_annotation_username"]

for fig, fig_info in zip(figs, fig_info_list):
self._plot_line_and_circle(fig, x=fig_info["x"], y=fig_info["y"], source=source, username=username,
color=color)

hover_tool = self._create_hover_tool(tooltip_item)
for fig in figs:
self._set_legend(fig, hover_tool)

bokeh.plotting.reset_output()
bokeh.plotting.output_file(f"{self.outdir}/{self.short_project_id}_アノテーション単位の累計グラフ.html",
title="アノテーション単位の累計グラフ")
bokeh.plotting.save(bokeh.layouts.column(figs))
write_cumulative_graph(fig_info_list_annotation_count, html_title="アノテーション単位の累計グラフ")

# 横軸が累計の入力データ数
fig_info_list_input_data_count = [
dict(x="cumulative_input_data_count", y="cumulative_annotation_worktime_hour", title="入力データ数と教師付作業時間の累積グラフ",
x_axis_label="入力データ数", y_axis_label="教師付作業時間[hour]"),
dict(x="cumulative_input_data_count", y="cumulative_inspection_worktime_hour",
title="入力データ数と中間検査作業時間の累積グラフ", x_axis_label="入力データ数", y_axis_label="中間検査作業時間[hour]"),
dict(x="cumulative_input_data_count", y="cumulative_acceptance_worktime_hour", title="入力データ数と受入作業時間の累積グラフ",
x_axis_label="入力データ数", y_axis_label="受入作業時間[hour]"),
dict(x="cumulative_input_data_count", y="cumulative_inspection_count", title="アノテーション数と検査コメント数の累積グラフ",
x_axis_label="入力データ数", y_axis_label="検査コメント数"),
]
write_cumulative_graph(fig_info_list_input_data_count, html_title="入力データ単位の累計グラフ")

fig_info_list_task_count = [
dict(x="cumulative_task_count", y="cumulative_annotation_worktime_hour", title="アノテーション数と教師付作業時間の累積グラフ",
x_axis_label="アノテーション数", y_axis_label="教師付作業時間[hour]"),
dict(x="cumulative_task_count", y="cumulative_inspection_worktime_hour", title="アノテーション数と中間検査作業時間の累積グラフ",
x_axis_label="アノテーション数", y_axis_label="中間検査作業時間[hour]"),
dict(x="cumulative_task_count", y="cumulative_acceptance_worktime_hour", title="アノテーション数と受入作業時間の累積グラフ",
x_axis_label="アノテーション数", y_axis_label="受入作業時間[hour]"),
dict(x="cumulative_task_count", y="cumulative_inspection_count", title="アノテーション数と検査コメント数の累積グラフ",
x_axis_label="アノテーション数", y_axis_label="検査コメント数"),
]
write_cumulative_graph(fig_info_list_task_count, html_title="タスク単位の累計グラフ")
7 changes: 6 additions & 1 deletion annofabcli/statistics/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,8 @@ def create_cumulative_df(task_df: pd.DataFrame) -> pd.DataFrame:
# 教師付の開始時刻でソートして、indexを更新する
df = task_df.sort_values(["first_annotation_account_id",
"first_annotation_started_datetime"]).reset_index(drop=True)

# タスクの累計数を取得するために設定する
df["task_count"] = 1
# 教師付の作業者でgroupby
groupby_obj = df.groupby("first_annotation_account_id")

Expand All @@ -557,7 +558,11 @@ def create_cumulative_df(task_df: pd.DataFrame) -> pd.DataFrame:
# タスク完了数、差し戻し数
df["cumulative_inspection_count"] = groupby_obj["inspection_count"].cumsum()
df["cumulative_annotation_count"] = groupby_obj["annotation_count"].cumsum()
df["cumulative_input_data_count"] = groupby_obj["input_data_count"].cumsum()
df["cumulative_task_count"] = groupby_obj["task_count"].cumsum()

# 元に戻す
df = df.drop(["task_count"], axis=1)
return df

def create_worktime_per_image_df(self, aggregation_by: AggregationBy, phase: TaskPhase) -> pd.DataFrame:
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
'pyquery',
'pandas',
'isodate',
'bokeh >=1.2.0',
'bokeh >=1.4.0',
'holoviews'],
python_requires='>=3.6',
classifiers=[
Expand Down

0 comments on commit 001e4f9

Please sign in to comment.