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}
-
+