From 1a7ac3ff3c828c9554d4b410eb2e70017305f47b Mon Sep 17 00:00:00 2001 From: Henry Cui Date: Sat, 27 Feb 2021 16:16:49 +0900 Subject: [PATCH] Add simple pareto front plot --- optuna_dashboard/static/apiClient.ts | 9 +++ .../static/components/GraphParetoFront.tsx | 60 +++++++++++++++++++ .../static/components/StudyDetail.tsx | 8 +++ optuna_dashboard/static/types/index.d.ts | 1 + 4 files changed, 78 insertions(+) create mode 100644 optuna_dashboard/static/components/GraphParetoFront.tsx diff --git a/optuna_dashboard/static/apiClient.ts b/optuna_dashboard/static/apiClient.ts index cd68c40a..befda07a 100644 --- a/optuna_dashboard/static/apiClient.ts +++ b/optuna_dashboard/static/apiClient.ts @@ -34,11 +34,17 @@ const convertTrialResponse = (res: TrialResponse): Trial => { } } +const convertTrialResponseList = (res: TrialResponse[]): Trial[] => { + return res.map((trial): Trial => convertTrialResponse(trial)) +} + + interface StudyDetailResponse { name: string datetime_start: string directions: StudyDirection[] best_trial?: TrialResponse + best_trials?: TrialResponse[] trials: TrialResponse[] } @@ -58,6 +64,9 @@ export const getStudyDetailAPI = (studyId: number): Promise => { best_trial: res.data.best_trial ? convertTrialResponse(res.data.best_trial) : undefined, + best_trials: res.data.best_trials + ? convertTrialResponseList(res.data.best_trials) + : undefined, trials: trials, } }) diff --git a/optuna_dashboard/static/components/GraphParetoFront.tsx b/optuna_dashboard/static/components/GraphParetoFront.tsx new file mode 100644 index 00000000..196e0a61 --- /dev/null +++ b/optuna_dashboard/static/components/GraphParetoFront.tsx @@ -0,0 +1,60 @@ +import * as plotly from "plotly.js-dist" +import React, { FC, useEffect } from "react" + +const plotDomId = "graph-pareto-front" + +export const GraphParetoFront: FC<{ + study: StudyDetail | null +}> = ({ study = null }) => { + + useEffect(() => { + if (study != null) { + plotParetoFront(study) + } + }, [study]) + + return
+} + +const plotParetoFront = (study: StudyDetail) => { + if (document.getElementById(plotDomId) === null) { + return + } + + if (study.directions.length != 2) { + return + } + + const layout: Partial = { + title: "Pareto-front plot", + margin: { + l: 50, + r: 50, + b: 0, + }, + } + + const trials: Trial[] = (study !== null) && study.best_trials ? study.best_trials : [] + console.log(study.best_trials) + console.log('length', trials.length) + if (trials.length === 0) { + plotly.react(plotDomId, [], layout) + return + } + + const pointColors = Array(trials.length).fill("blue") + + const plotData: Partial[] = [ + { + type: "scatter", + x: trials.map((t: Trial): number => t.values![0]), + y: trials.map((t: Trial): number => t.values![1]), + mode: "markers", + marker: { + color: pointColors, + }, + }, + ] + + plotly.react(plotDomId, plotData, layout) +} diff --git a/optuna_dashboard/static/components/StudyDetail.tsx b/optuna_dashboard/static/components/StudyDetail.tsx index d4068fec..85e4dc7e 100644 --- a/optuna_dashboard/static/components/StudyDetail.tsx +++ b/optuna_dashboard/static/components/StudyDetail.tsx @@ -23,6 +23,7 @@ import { GraphParallelCoordinate } from "./GraphParallelCoordinate" import { GraphIntermediateValues } from "./GraphIntermediateValues" import { GraphSlice } from "./GraphSlice" import { GraphHistory } from "./GraphHistory" +import { GraphParetoFront } from "./GraphParetoFront" import { actionCreator } from "../action" import { studyDetailsState } from "../state" @@ -203,6 +204,13 @@ export const StudyDetail: FC = () => { ) : null} + {studyDetail !== null && !isSingleObjectiveStudy(studyDetail) ? ( + + + + + + ) : null} diff --git a/optuna_dashboard/static/types/index.d.ts b/optuna_dashboard/static/types/index.d.ts index a534a02f..295a24c7 100644 --- a/optuna_dashboard/static/types/index.d.ts +++ b/optuna_dashboard/static/types/index.d.ts @@ -54,6 +54,7 @@ declare interface StudyDetail { directions: StudyDirection[] datetime_start: Date best_trial?: Trial + best_trials?: Trial[] trials: Trial[] }