From 6d4f0238bbd1068fef5b8d0074f33a7df93e38ca Mon Sep 17 00:00:00 2001 From: Harman Waseer <2403hwaseer@gmail.com> Date: Sat, 6 Mar 2021 11:05:59 +0530 Subject: [PATCH] Plot contour for two parameters --- .../static/components/GraphContour.tsx | 197 ++++++++++-------- .../static/components/StudyDetail.tsx | 14 +- 2 files changed, 116 insertions(+), 95 deletions(-) diff --git a/optuna_dashboard/static/components/GraphContour.tsx b/optuna_dashboard/static/components/GraphContour.tsx index 100d20d0..c699835b 100644 --- a/optuna_dashboard/static/components/GraphContour.tsx +++ b/optuna_dashboard/static/components/GraphContour.tsx @@ -1,27 +1,27 @@ import * as plotly from "plotly.js-dist" -import React, {FC, useEffect} from "react" +import React, { FC, useEffect } from "react" const plotDomId = "graph-contour" -export const GraphContour: FC <{ - trials: Trial[] +export const GraphContour: FC<{ + trials: Trial[] }> = ({ trials = [] }) => { - useEffect(() => { - plotContour(trials, 0) - }, [trials]) - return
+ useEffect(() => { + plotContour(trials, 0) + }, [trials]) + return
} const plotContour = (trials: Trial[], objectiveId: number) => { - if (document.getElementById(plotDomId) === null){ + if (document.getElementById(plotDomId) === null) { return } const layout: Partial = { title: "Contour", margin: { - l:50, - r:50, + l: 50, + r: 50, }, } @@ -30,89 +30,110 @@ const plotContour = (trials: Trial[], objectiveId: number) => { } const filteredTrials = trials.filter( - (t) => t.state === "Complete" || t.state === "Pruned" + (t) => t.state === "Complete" || t.state === "Pruned" ) - let paramNames = new Set(trials[0]. params.map((p) => p.name)) + let paramNames = new Set(trials[0].params.map((p) => p.name)) filteredTrials.forEach((t) => { - paramNames = new Set( - t.params.filter((p) => paramNames.has(p.name)).map((p) => p.name) - ) + paramNames = new Set( + t.params.filter((p) => paramNames.has(p.name)).map((p) => p.name) + ) }) - if (paramNames.size === 0 || paramNames.size === 1){ - plotly.react(plotDomId, []) - return - } - const objectiveValues: number[] = filteredTrials.map( - (t) => t.values![objectiveId] - ) - let paramValues: {[key:number]:number[]} = [] - - let i=0 - if(paramNames.size === 2){ - paramNames.forEach((paramName) => { - const valueStrings = filteredTrials.map((t) => { - const param = t.params.find((p) => p.name == paramName) - return param!.value - }) - const values: number[] = valueStrings.map((v) => parseFloat(v)) - paramValues[i] = values - i++ - }) - - let x_indice: number[] = paramValues[0].sort() - let y_indice: number[] = paramValues[1].sort() - console.log(x_indice) - console.log(y_indice) - - let data: Partial[] = [ - { - type: "contour", - // z: [objectiveValues], - // x: [0,1,2,3,4,5,6,7,8,9], - // y: [0,1,2,3,4,5,6,7,8,9], - z: [[null, 6555.432866248336, 6398.264431306621, null, null, null, 940.4341819980103, 1010.8139523862947, null, null, 7181.640254856135, null], [null, null, null, 5045.796883055694, null, 409.8829237095467, null, null, null, 2422.8488853595736, null, null], [null, null, null, null, 428.6133223375032, null, null, null, 1051.2032089247634, null, null, null]], - - x:[-89.25791599036862, -80.97180290847139, -79.99540256356374, -71.03377283416455, -20.67881336869945, -20.245565531976297, 30.68279944851855, 31.809023128450434, 32.4068389221282, 49.22244290320802, 84.75045872947317, 93.0365718113704], - y:['-1', '0', '1'], - mode: "markers", - marker:{ - color: "#000" - }, - line:{ - color: "#000" - }, - //@ts-ignore - colorbar:{ - title: "Objective Value" - }, - colorscale: "Blues", - connectgaps: true, - contours_coloring: "heatmap", - hoverinfo: "none", - line_smoothing: 1.3, - - - } - ] - let updateLayout: Partial = { - title: "Contour", - margin: { - l:50, - r:50 - }, - } - - console.log(data) - console.log(paramValues[0]) - console.log(paramValues[1]) - console.log([[objectiveValues],[objectiveValues]]) - - plotly.react(plotDomId, data, updateLayout) -} -else { + if (paramNames.size === 0 || paramNames.size === 1) { plotly.react(plotDomId, []) return + } + const objectiveValues: number[] = filteredTrials.map( + (t) => t.values![objectiveId] + ) + + let paramValuesNumeric: { [key: number]: number[] } = [] + let paramValues: { [key: number]: string[]} = [] + + let i = 0 + if (paramNames.size === 2) { + paramNames.forEach((paramName) => { + const valueStrings = filteredTrials.map((t) => { + const param = t.params.find((p) => p.name == paramName) + return param!.value + }) + const values: number[] = valueStrings.map((v) => parseFloat(v)) + paramValuesNumeric[i] = values + paramValues[i] = valueStrings + i++ + }) + + let x_indice = paramValuesNumeric[0].sort((a,b) => a>b ? 1: -1).map(String) + let y_indice = paramValuesNumeric[1].sort((a,b) => a>b ? 1: -1).map(String) + + + let x_indices : string[] =[] + let y_indices : string[] =[] + x_indice.forEach(element => { + if(!x_indices.includes(element)){ + x_indices.push(element) + } + }) + y_indice.forEach(element => { + if(!y_indices.includes(element)){ + y_indices.push(element) + } + }) + let z: number[][] = [] + for(let j=0; j[] = [ + { + type: "contour", + z: z, + x: x_indices, + y: y_indices, + mode: "markers", + marker: { + color: "#000", + }, + line: { + color: "#000", + }, + //@ts-ignore + colorbar: { + title: "Objective Value", + }, + colorscale: "Blues", + connectgaps: true, + contours_coloring: "heatmap", + hoverinfo: "none", + line_smoothing: 1.3, + }, + { + type: "scatter", + x: paramValues[0], + y: paramValues[1], + mode: "markers", + marker: { + color: "#000" + } + } + ] + let updateLayout: Partial = { + title: "Contour", + margin: { + l: 50, + r: 50, + }, + } + + plotly.react(plotDomId, data, updateLayout) + } else { + plotly.react(plotDomId, []) + return + } } -} \ No newline at end of file diff --git a/optuna_dashboard/static/components/StudyDetail.tsx b/optuna_dashboard/static/components/StudyDetail.tsx index 816398be..f29b4d1d 100644 --- a/optuna_dashboard/static/components/StudyDetail.tsx +++ b/optuna_dashboard/static/components/StudyDetail.tsx @@ -196,12 +196,12 @@ export const StudyDetail: FC = () => { - - - - - - + + + + + + ) : null} {studyDetail !== null && isSingleObjectiveStudy(studyDetail) ? ( @@ -211,7 +211,7 @@ export const StudyDetail: FC = () => { ) : null} - +