Merge pull request #805 from knshnb/top-plot-backend

Support backend rendering of plots in the top page
This commit is contained in:
c-bata authored and GitHub committed 2024-02-16 10:41:21 +09:00
commit 09f61ce23c
5 files changed
+149 -1

No files matched your search

+6
View File
@@ -283,6 +283,12 @@ def create_app(
fig = optuna.visualization.plot_rank(study)
elif plot_type == "edf":
fig = optuna.visualization.plot_edf(study)
elif plot_type == "timeline":
fig = optuna.visualization.plot_timeline(study)
elif plot_type == "param_importances":
fig = optuna.visualization.plot_param_importances(study)
elif plot_type == "pareto_front":
fig = optuna.visualization.plot_pareto_front(study)
else:
response.status = 404 # Not found
return {"reason": f"plot_type={plot_type} is not supported."}
+3
View File
@@ -452,6 +452,9 @@ export enum PlotType {
ParallelCoordinate = "parallel_coordinate",
Rank = "rank",
EDF = "edf",
Timeline = "timeline",
ParamImportances = "param_importances",
ParetoFront = "pareto_front",
}
export const getPlotAPI = (
studyId: number,
@@ -3,7 +3,13 @@ import React, { FC, useEffect } from "react"
import { Typography, useTheme, Box, Card, CardContent } from "@mui/material"
import { useParamImportance } from "../hooks/useParamImportance"
import { useStudyDirections, usePlotlyColorTheme } from "../state"
import {
useStudyDirections,
usePlotlyColorTheme,
useBackendRender,
} from "../state"
import { PlotType } from "../apiClient"
import { usePlot } from "../hooks/usePlot"
const plotDomId = "graph-hyperparameter-importances"
@@ -11,6 +17,57 @@ export const GraphHyperparameterImportance: FC<{
studyId: number
study: StudyDetail | null
graphHeight: string
}> = ({ studyId, study = null, graphHeight }) => {
if (useBackendRender()) {
return (
<GraphHyperparameterImportanceBackend
studyId={studyId}
study={study}
graphHeight={graphHeight}
/>
)
} else {
return (
<GraphHyperparameterImportanceFrontend
studyId={studyId}
study={study}
graphHeight={graphHeight}
/>
)
}
}
const GraphHyperparameterImportanceBackend: FC<{
studyId: number
study: StudyDetail | null
graphHeight: string
}> = ({ studyId, study = null, graphHeight }) => {
const numCompletedTrials =
study?.trials.filter((t) => t.state === "Complete").length || 0
const { data, layout, error } = usePlot({
numCompletedTrials,
studyId,
plotType: PlotType.ParamImportances,
})
useEffect(() => {
if (data && layout) {
plotly.react(plotDomId, data, layout)
}
}, [data, layout])
useEffect(() => {
if (error) {
console.error(error)
}
}, [error])
return <Box id={plotDomId} sx={{ height: graphHeight }} />
}
const GraphHyperparameterImportanceFrontend: FC<{
studyId: number
study: StudyDetail | null
graphHeight: string
}> = ({ studyId, study = null, graphHeight }) => {
const theme = useTheme()
const colorTheme = usePlotlyColorTheme(theme.palette.mode)
@@ -14,11 +14,50 @@ import {
import { makeHovertext } from "../graphUtil"
import { usePlotlyColorTheme } from "../state"
import { useNavigate } from "react-router-dom"
import { PlotType } from "../apiClient"
import { useBackendRender } from "../state"
import { usePlot } from "../hooks/usePlot"
const plotDomId = "graph-pareto-front"
export const GraphParetoFront: FC<{
study: StudyDetail | null
}> = ({ study = null }) => {
if (useBackendRender()) {
return <GraphParetoFrontBackend study={study} />
} else {
return <GraphParetoFrontFrontend study={study} />
}
}
const GraphParetoFrontBackend: FC<{
study: StudyDetail | null
}> = ({ study = null }) => {
const studyId = study?.id
const numCompletedTrials =
study?.trials.filter((t) => t.state === "Complete").length || 0
const { data, layout, error } = usePlot({
numCompletedTrials,
studyId,
plotType: PlotType.ParetoFront,
})
useEffect(() => {
if (data && layout) {
plotly.react(plotDomId, data, layout)
}
}, [data, layout])
useEffect(() => {
if (error) {
console.error(error)
}
}, [error])
return <Box id={plotDomId} sx={{ height: "450px" }} />
}
const GraphParetoFrontFrontend: FC<{
study: StudyDetail | null
}> = ({ study = null }) => {
const theme = useTheme()
const colorTheme = usePlotlyColorTheme(theme.palette.mode)
@@ -3,12 +3,55 @@ import React, { FC, useEffect } from "react"
import { Card, CardContent, Grid, Typography, useTheme } from "@mui/material"
import { makeHovertext } from "../graphUtil"
import { usePlotlyColorTheme } from "../state"
import { PlotType } from "../apiClient"
import { useBackendRender } from "../state"
import { usePlot } from "../hooks/usePlot"
const plotDomId = "graph-timeline"
const maxBars = 100
export const GraphTimeline: FC<{
study: StudyDetail | null
}> = ({ study }) => {
if (useBackendRender()) {
return <GraphTimelineBackend study={study} />
} else {
return <GraphTimelineFrontend study={study} />
}
}
const GraphTimelineBackend: FC<{
study: StudyDetail | null
}> = ({ study }) => {
const studyId = study?.id
const numCompletedTrials =
study?.trials.filter((t) => t.state === "Complete").length || 0
const { data, layout, error } = usePlot({
numCompletedTrials,
studyId,
plotType: PlotType.Timeline,
})
useEffect(() => {
if (data && layout) {
plotly.react(plotDomId, data, layout)
}
}, [data, layout])
useEffect(() => {
if (error) {
console.error(error)
}
}, [error])
return (
<Grid item xs={9}>
<div id={plotDomId} />
</Grid>
)
}
const GraphTimelineFrontend: FC<{
study: StudyDetail | null
}> = ({ study }) => {
const theme = useTheme()
const colorTheme = usePlotlyColorTheme(theme.palette.mode)