From 9f7c545322200c5025a984c54d977e7de80c099b Mon Sep 17 00:00:00 2001 From: Advitya Gemawat Date: Wed, 24 Jan 2024 15:05:04 -0500 Subject: [PATCH 1/4] PL Support on raiwidgets (#2500) * pl support * python lint fixes * Updated rai_core_flask requirement --- raiwidgets/raiwidgets/dashboard.py | 5 ++++- raiwidgets/raiwidgets/responsibleai_dashboard.py | 7 ++++++- raiwidgets/requirements.txt | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/raiwidgets/raiwidgets/dashboard.py b/raiwidgets/raiwidgets/dashboard.py index c70f2d4816..c0b00a9da6 100644 --- a/raiwidgets/raiwidgets/dashboard.py +++ b/raiwidgets/raiwidgets/dashboard.py @@ -61,6 +61,7 @@ def __init__(self, *, port, locale, no_inline_dashboard=False, + is_private_link=False, **kwargs): """Initialize the dashboard.""" @@ -68,7 +69,9 @@ def __init__(self, *, raise ValueError("Required parameters not provided") try: - self._service = FlaskHelper(ip=public_ip, port=port) + self._service = FlaskHelper(ip=public_ip, + port=port, + is_private_link=is_private_link) except Exception as e: self._service = None raise e diff --git a/raiwidgets/raiwidgets/responsibleai_dashboard.py b/raiwidgets/raiwidgets/responsibleai_dashboard.py index fc194258ad..3ac0a11fff 100644 --- a/raiwidgets/raiwidgets/responsibleai_dashboard.py +++ b/raiwidgets/raiwidgets/responsibleai_dashboard.py @@ -29,10 +29,14 @@ class ResponsibleAIDashboard(Dashboard): :param cohort_list: List of cohorts defined by the user for the dashboard. :type cohort_list: List[Cohort] + :param is_private_link: If the dashboard environment is + a private link AML workspace. + :type is_private_link: bool """ def __init__(self, analysis: RAIInsights, public_ip=None, port=None, locale=None, - cohort_list=None, **kwargs): + cohort_list=None, is_private_link=False, + **kwargs): self.input = ResponsibleAIDashboardInput( analysis, cohort_list=cohort_list) @@ -43,6 +47,7 @@ def __init__(self, analysis: RAIInsights, port=port, locale=locale, no_inline_dashboard=True, + is_private_link=is_private_link, **kwargs) def predict(): diff --git a/raiwidgets/requirements.txt b/raiwidgets/requirements.txt index 0bac7cde2a..be5d8cddb7 100644 --- a/raiwidgets/requirements.txt +++ b/raiwidgets/requirements.txt @@ -1,7 +1,7 @@ numpy>=1.17.2,<=1.26.2 pandas>=0.25.1,<2.0.0 scipy>=1.4.1 -rai-core-flask==0.7.2 +rai-core-flask==0.7.3 itsdangerous<=2.1.2 scikit-learn>=0.22.1 lightgbm>=2.0.11 From 6973ee4ed32e6bc3ec9b64853acd3292f282775f Mon Sep 17 00:00:00 2001 From: Advitya Gemawat Date: Wed, 24 Jan 2024 16:24:40 -0500 Subject: [PATCH 2/4] Flyout Bounding Box legend & accessibility fixes (#2497) * added bb legend * added tokens variables * localization & accessibility fixes * simplified stack * refactor * refactor * refactor * new file component refactor * auto lint fixes --- .../Controls/DetectionDetails.tsx | 51 ++++++++++++ .../Controls/FlyoutObjectDetection.tsx | 81 ++++++++----------- .../Controls/FlyoutObjectDetectionUtils.tsx | 41 +++++++++- libs/localization/src/lib/en.json | 1 + 4 files changed, 123 insertions(+), 51 deletions(-) create mode 100644 libs/interpret-vision/src/lib/VisionExplanationDashboard/Controls/DetectionDetails.tsx diff --git a/libs/interpret-vision/src/lib/VisionExplanationDashboard/Controls/DetectionDetails.tsx b/libs/interpret-vision/src/lib/VisionExplanationDashboard/Controls/DetectionDetails.tsx new file mode 100644 index 0000000000..2daf59ebcb --- /dev/null +++ b/libs/interpret-vision/src/lib/VisionExplanationDashboard/Controls/DetectionDetails.tsx @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { Stack, Text } from "@fluentui/react"; +import { IVisionListItem } from "@responsible-ai/core-ui"; +import { localization } from "@responsible-ai/localization"; +import React from "react"; + +import { stackTokens } from "./FlyoutObjectDetectionUtils"; + +interface IDetectionDetailsProps { + item: IVisionListItem; // replace with actual type + correctDetections: string; + incorrectDetections: string; +} +export class DetectionDetails extends React.Component { + public render(): React.ReactNode { + return ( + + + + + {localization.InterpretVision.Dashboard.indexLabel} + {this.props.item?.index} + + + + + {localization.InterpretVision.Dashboard.correctDetections} + {this.props.correctDetections} + + + + + {localization.InterpretVision.Dashboard.incorrectDetections} + {this.props.incorrectDetections} + + + + ); + } +} diff --git a/libs/interpret-vision/src/lib/VisionExplanationDashboard/Controls/FlyoutObjectDetection.tsx b/libs/interpret-vision/src/lib/VisionExplanationDashboard/Controls/FlyoutObjectDetection.tsx index d32c30cdc6..87eec60108 100644 --- a/libs/interpret-vision/src/lib/VisionExplanationDashboard/Controls/FlyoutObjectDetection.tsx +++ b/libs/interpret-vision/src/lib/VisionExplanationDashboard/Controls/FlyoutObjectDetection.tsx @@ -7,6 +7,7 @@ import { IComboBox, IComboBoxOption, Image, + Label, List, Panel, PanelType, @@ -24,6 +25,7 @@ import * as FlyoutStyles from "../utils/FlyoutUtils"; import { getObjectDetectionImageAltText } from "../utils/getAltTextUtils"; import { getJoinedLabelString } from "../utils/labelUtils"; +import { DetectionDetails } from "./DetectionDetails"; import { flyoutStyles, explanationImage, @@ -122,42 +124,11 @@ export class FlyoutObjectDetection extends React.Component< verticalAlign="center" > - - - - - {localization.InterpretVision.Dashboard.indexLabel} - {item?.index} - - - - - { - localization.InterpretVision.Dashboard - .correctDetections - } - {correctDetections} - - - - - { - localization.InterpretVision.Dashboard - .incorrectDetections - } - {incorrectDetections} - - - + @@ -173,13 +144,17 @@ export class FlyoutObjectDetection extends React.Component< {localization.InterpretVision.Dashboard.panelInformation} - + + @@ -200,17 +175,27 @@ export class FlyoutObjectDetection extends React.Component< - { - - } + + {!this.props.loadingExplanation[item.index][ +this.state.odSelectedKey.slice( diff --git a/libs/interpret-vision/src/lib/VisionExplanationDashboard/Controls/FlyoutObjectDetectionUtils.tsx b/libs/interpret-vision/src/lib/VisionExplanationDashboard/Controls/FlyoutObjectDetectionUtils.tsx index 192a05e0aa..6de3e33643 100644 --- a/libs/interpret-vision/src/lib/VisionExplanationDashboard/Controls/FlyoutObjectDetectionUtils.tsx +++ b/libs/interpret-vision/src/lib/VisionExplanationDashboard/Controls/FlyoutObjectDetectionUtils.tsx @@ -1,9 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { IComboBoxOption, getTheme } from "@fluentui/react"; +import { IComboBoxOption, getTheme, Stack, Text } from "@fluentui/react"; import { IDataset, IVisionListItem } from "@responsible-ai/core-ui"; import { localization } from "@responsible-ai/localization"; +import React from "react"; import { CanvasTools } from "vott-ct"; import { Editor } from "vott-ct/lib/js/CanvasTools/CanvasTools.Editor"; import { RegionData } from "vott-ct/lib/js/CanvasTools/Core/RegionData"; @@ -31,6 +32,42 @@ export const stackTokens = { large: { childrenGap: "l2" }, medium: { childrenGap: "l1" } }; + +const theme = getTheme(); + +export class ColorLegend extends React.Component { + public render(): React.ReactNode { + return ( + + + + {localization.InterpretVision.Dashboard.trueY} + +
+ + + + {localization.InterpretVision.Dashboard.predictedY} + +
+ + + ); + } +} + export const ExcessLabelLen = localization.InterpretVision.Dashboard.prefix.length; @@ -109,8 +146,6 @@ export function drawBoundingBoxes( return; } - const theme = getTheme(); - // Ensuring object detection labels are populated if ( !dataset.object_detection_predicted_y || diff --git a/libs/localization/src/lib/en.json b/libs/localization/src/lib/en.json index c9d6c44baa..4f98babeb2 100644 --- a/libs/localization/src/lib/en.json +++ b/libs/localization/src/lib/en.json @@ -1477,6 +1477,7 @@ "multiselect": "Multiselect", "notdefined": "object scenario not defined", "objectSelect": "Object Selection", + "objectSelectionLabel": "objectSelectLabel", "pageSize": "Page size: ", "panelTitle": "Selected instance", "panelExplanation": "Explanation", From 7ff3476a5cf839cd2fb5d0fb8894400773d83c26 Mon Sep 17 00:00:00 2001 From: Advitya Gemawat Date: Thu, 25 Jan 2024 18:42:18 -0500 Subject: [PATCH 3/4] Dropdown option fix (#2505) * dropdown option fix * auto lint fixes --- .../Controls/FlyoutObjectDetection.tsx | 6 ++++-- .../lib/VisionExplanationDashboard/utils/FlyoutUtils.tsx | 7 ++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/libs/interpret-vision/src/lib/VisionExplanationDashboard/Controls/FlyoutObjectDetection.tsx b/libs/interpret-vision/src/lib/VisionExplanationDashboard/Controls/FlyoutObjectDetection.tsx index 87eec60108..12909ba053 100644 --- a/libs/interpret-vision/src/lib/VisionExplanationDashboard/Controls/FlyoutObjectDetection.tsx +++ b/libs/interpret-vision/src/lib/VisionExplanationDashboard/Controls/FlyoutObjectDetection.tsx @@ -57,7 +57,8 @@ export class FlyoutObjectDetection extends React.Component< const selectableObjectIndexes = FlyoutStyles.generateSelectableObjectDetectionIndexes( localization.InterpretVision.Dashboard.prefix, - item + item, + this.props.dataset.class_names ); this.setState({ item, metadata, selectableObjectIndexes }); } @@ -75,7 +76,8 @@ export class FlyoutObjectDetection extends React.Component< const selectableObjectIndexes = FlyoutStyles.generateSelectableObjectDetectionIndexes( localization.InterpretVision.Dashboard.prefix, - item + item, + this.props.dataset.class_names ); this.setState({ item: this.props.item, diff --git a/libs/interpret-vision/src/lib/VisionExplanationDashboard/utils/FlyoutUtils.tsx b/libs/interpret-vision/src/lib/VisionExplanationDashboard/utils/FlyoutUtils.tsx index 57ce7520bc..b78f482f7c 100644 --- a/libs/interpret-vision/src/lib/VisionExplanationDashboard/utils/FlyoutUtils.tsx +++ b/libs/interpret-vision/src/lib/VisionExplanationDashboard/utils/FlyoutUtils.tsx @@ -34,13 +34,14 @@ export function onRenderCell( export function generateSelectableObjectDetectionIndexes( prefix: string, - item: IVisionListItem | undefined + item: IVisionListItem | undefined, + classNames: string[] | undefined ): IComboBoxOption[] { const temp = item?.odPredictedY; const selectableObjectIndexes: IComboBoxOption[] = []; - if (temp) { + if (temp && classNames) { for (let i = 0; i < Object.values(temp).length; i++) { - const className = item?.predictedY[i]; + const className = classNames[temp[i][0] - 1]; selectableObjectIndexes.push({ key: prefix + String(i), text: String(i) + String(": ") + className From f1cf49c3f42e3dc00603db9793500583d16b02a8 Mon Sep 17 00:00:00 2001 From: Ilya Matiach Date: Fri, 26 Jan 2024 13:15:25 -0500 Subject: [PATCH 4/4] update UI to support genai task for RAI text dashboard (#2504) (#2508) --- apps/dashboard/src/app/textApplications.ts | 5 ++ .../mockForecastingDataSingleTimeSeries.ts | 10 ++-- .../__mock_data__/squadGenai.ts | 59 +++++++++++++++++++ libs/core-ui/src/lib/DatasetCohort.ts | 2 +- libs/core-ui/src/lib/Interfaces/IDataset.ts | 5 +- .../lib/util/datasetUtils/getColumnRanges.ts | 6 +- .../util/datasetUtils/getPropertyValues.ts | 10 +++- .../TextLocalImportancePlots.tsx | 2 +- .../ModelOverview/ConfusionMatrixHeatmap.tsx | 2 +- .../Controls/TabsView/TabsView.tsx | 1 + 10 files changed, 89 insertions(+), 13 deletions(-) create mode 100644 apps/dashboard/src/model-assessment-text/__mock_data__/squadGenai.ts diff --git a/apps/dashboard/src/app/textApplications.ts b/apps/dashboard/src/app/textApplications.ts index 4adb44754e..56c072dbc8 100644 --- a/apps/dashboard/src/app/textApplications.ts +++ b/apps/dashboard/src/app/textApplications.ts @@ -17,6 +17,7 @@ import { emotionModelExplanationData } from "../model-assessment-text/__mock_data__/emotion"; import { squad } from "../model-assessment-text/__mock_data__/squad"; +import { squadGenai } from "../model-assessment-text/__mock_data__/squadGenai"; import { IDataSet, @@ -65,6 +66,10 @@ export const textApplications: ITextApplications = { squad: { classDimension: 3, dataset: squad + } as IModelAssessmentDataSet, + squadGenai: { + classDimension: 3, + dataset: squadGenai } as IModelAssessmentDataSet }, versions: { "1": 1, "2:Static-View": 2 } diff --git a/apps/dashboard/src/model-assessment-forecasting/__mock_data__/mockForecastingDataSingleTimeSeries.ts b/apps/dashboard/src/model-assessment-forecasting/__mock_data__/mockForecastingDataSingleTimeSeries.ts index 6457722b82..fe807c0f87 100644 --- a/apps/dashboard/src/model-assessment-forecasting/__mock_data__/mockForecastingDataSingleTimeSeries.ts +++ b/apps/dashboard/src/model-assessment-forecasting/__mock_data__/mockForecastingDataSingleTimeSeries.ts @@ -28,7 +28,9 @@ mockForecastingDataSingleTimeSeries.predicted_y = startingIndexBobsSandwichesTimeSeries, endingIndexBobsSandwichesTimeSeries ); -mockForecastingDataSingleTimeSeries.true_y = mockForecastingData.true_y.slice( - startingIndexBobsSandwichesTimeSeries, - endingIndexBobsSandwichesTimeSeries -); +if (mockForecastingData.true_y) { + mockForecastingDataSingleTimeSeries.true_y = mockForecastingData.true_y.slice( + startingIndexBobsSandwichesTimeSeries, + endingIndexBobsSandwichesTimeSeries + ); +} diff --git a/apps/dashboard/src/model-assessment-text/__mock_data__/squadGenai.ts b/apps/dashboard/src/model-assessment-text/__mock_data__/squadGenai.ts new file mode 100644 index 0000000000..52b0007b04 --- /dev/null +++ b/apps/dashboard/src/model-assessment-text/__mock_data__/squadGenai.ts @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { DatasetTaskType, IDataset } from "@responsible-ai/core-ui"; + +export const squadGenai: IDataset = { + categorical_features: [], + class_names: undefined, + feature_names: [ + "context", + "prompt", + "positive_words", + "negative_words", + "negation_words", + "negated_entities", + "named_persons", + "sentence_length" + ], + features: [ + [ + 'Architecturally, the school has a Catholic character. Atop the Main Building\'s gold dome is a golden statue of the Virgin Mary. Immediately in front of the Main Building and facing it, is a copper statue of Christ with arms upraised with the legend "Venite Ad Me Omnes". Next to the Main Building is the Basilica of the Sacred Heart. Immediately behind the basilica is the Grotto, a Marian place of prayer and reflection. It is a replica of the grotto at Lourdes, France where the Virgin Mary reputedly appeared to Saint Bernadette Soubirous in 1858. At the end of the main drive (and in a direct line that connects through 3 statues and the Gold Dome), is a simple, modern stone statue of Mary.', + 'Answer the question given the context.\n\ncontext:\nArchitecturally, the school has a Catholic character. Atop the Main Building\'s gold dome is a golden statue of the Virgin Mary. Immediately in front of the Main Building and facing it, is a copper statue of Christ with arms upraised with the legend "Venite Ad Me Omnes". Next to the Main Building is the Basilica of the Sacred Heart. Immediately behind the basilica is the Grotto, a Marian place of prayer and reflection. It is a replica of the grotto at Lourdes, France where the Virgin Mary reputedly appeared to Saint Bernadette Soubirous in 1858. At the end of the main drive (and in a direct line that connects through 3 statues and the Gold Dome), is a simple, modern stone statue of Mary.\n\nquestion:\nTo whom did the Virgin Mary allegedly appear in 1858 in Lourdes France?', + 50, + 0, + 0, + 0, + 3, + 827 + ], + [ + 'Architecturally, the school has a Catholic character. Atop the Main Building\'s gold dome is a golden statue of the Virgin Mary. Immediately in front of the Main Building and facing it, is a copper statue of Christ with arms upraised with the legend "Venite Ad Me Omnes". Next to the Main Building is the Basilica of the Sacred Heart. Immediately behind the basilica is the Grotto, a Marian place of prayer and reflection. It is a replica of the grotto at Lourdes, France where the Virgin Mary reputedly appeared to Saint Bernadette Soubirous in 1858. At the end of the main drive (and in a direct line that connects through 3 statues and the Gold Dome), is a simple, modern stone statue of Mary.', + 'Answer the question given the context.\n\ncontext:\nArchitecturally, the school has a Catholic character. Atop the Main Building\'s gold dome is a golden statue of the Virgin Mary. Immediately in front of the Main Building and facing it, is a copper statue of Christ with arms upraised with the legend "Venite Ad Me Omnes". Next to the Main Building is the Basilica of the Sacred Heart. Immediately behind the basilica is the Grotto, a Marian place of prayer and reflection. It is a replica of the grotto at Lourdes, France where the Virgin Mary reputedly appeared to Saint Bernadette Soubirous in 1858. At the end of the main drive (and in a direct line that connects through 3 statues and the Gold Dome), is a simple, modern stone statue of Mary.\n\nquestion:\nWhat is in front of the Notre Dame Main Building?', + 50, + 0, + 0, + 0, + 2, + 805 + ], + [ + 'Architecturally, the school has a Catholic character. Atop the Main Building\'s gold dome is a golden statue of the Virgin Mary. Immediately in front of the Main Building and facing it, is a copper statue of Christ with arms upraised with the legend "Venite Ad Me Omnes". Next to the Main Building is the Basilica of the Sacred Heart. Immediately behind the basilica is the Grotto, a Marian place of prayer and reflection. It is a replica of the grotto at Lourdes, France where the Virgin Mary reputedly appeared to Saint Bernadette Soubirous in 1858. At the end of the main drive (and in a direct line that connects through 3 statues and the Gold Dome), is a simple, modern stone statue of Mary.', + 'Answer the question given the context.\n\ncontext:\nArchitecturally, the school has a Catholic character. Atop the Main Building\'s gold dome is a golden statue of the Virgin Mary. Immediately in front of the Main Building and facing it, is a copper statue of Christ with arms upraised with the legend "Venite Ad Me Omnes". Next to the Main Building is the Basilica of the Sacred Heart. Immediately behind the basilica is the Grotto, a Marian place of prayer and reflection. It is a replica of the grotto at Lourdes, France where the Virgin Mary reputedly appeared to Saint Bernadette Soubirous in 1858. At the end of the main drive (and in a direct line that connects through 3 statues and the Gold Dome), is a simple, modern stone statue of Mary.\n\nquestion:\nThe Basilica of the Sacred heart at Notre Dame is beside to which structure?', + 52, + 0, + 0, + 0, + 3, + 832 + ] + ], + predicted_y: [ + "This is a dummy answer", + "This is a dummy answer", + "This is a dummy answer" + ], + target_column: undefined, + task_type: DatasetTaskType.GenerativeText, + true_y: undefined +}; diff --git a/libs/core-ui/src/lib/DatasetCohort.ts b/libs/core-ui/src/lib/DatasetCohort.ts index 74f92049ed..4753abed90 100644 --- a/libs/core-ui/src/lib/DatasetCohort.ts +++ b/libs/core-ui/src/lib/DatasetCohort.ts @@ -120,7 +120,7 @@ export class DatasetCohort { dataDict[index][featureName] = val; }); }); - this.dataset.true_y.forEach((val, index) => { + this.dataset.true_y?.forEach((val, index) => { if (Array.isArray(val)) { val.forEach((subVal, subIndex) => { dataDict[index][DatasetCohortColumns.TrueY + subIndex.toString()] = diff --git a/libs/core-ui/src/lib/Interfaces/IDataset.ts b/libs/core-ui/src/lib/Interfaces/IDataset.ts index ea05d3df2e..832c8d4e01 100644 --- a/libs/core-ui/src/lib/Interfaces/IDataset.ts +++ b/libs/core-ui/src/lib/Interfaces/IDataset.ts @@ -13,7 +13,8 @@ export enum DatasetTaskType { MultilabelImageClassification = "multilabel_image_classification", Forecasting = "forecasting", ObjectDetection = "object_detection", - QuestionAnswering = "question_answering" + QuestionAnswering = "question_answering", + GenerativeText = "generative_text" } export interface ITabularDatasetMetadata { @@ -31,7 +32,7 @@ export interface IObjectDetectionLabelType { export interface IDataset { task_type: DatasetTaskType; - true_y: number[] | number[][] | string[]; + true_y?: number[] | number[][] | string[]; predicted_y?: number[] | number[][] | string[]; probability_y?: number[][]; features: unknown[][]; diff --git a/libs/core-ui/src/lib/util/datasetUtils/getColumnRanges.ts b/libs/core-ui/src/lib/util/datasetUtils/getColumnRanges.ts index c1b84bd144..61fde5cabf 100644 --- a/libs/core-ui/src/lib/util/datasetUtils/getColumnRanges.ts +++ b/libs/core-ui/src/lib/util/datasetUtils/getColumnRanges.ts @@ -161,7 +161,11 @@ function getRegressionErrorFeatureRange( dataset: IDataset, modelType: ModelTypes ): IColumnRange | undefined { - if (modelType === ModelTypes.Regression && dataset.predicted_y) { + if ( + modelType === ModelTypes.Regression && + dataset.predicted_y && + dataset.true_y + ) { const regressionErrors = []; for (let index = 0; index < dataset.features.length; index++) { const trueY = dataset.true_y[index]; diff --git a/libs/core-ui/src/lib/util/datasetUtils/getPropertyValues.ts b/libs/core-ui/src/lib/util/datasetUtils/getPropertyValues.ts index 638e152929..eeb5bd7477 100644 --- a/libs/core-ui/src/lib/util/datasetUtils/getPropertyValues.ts +++ b/libs/core-ui/src/lib/util/datasetUtils/getPropertyValues.ts @@ -44,9 +44,12 @@ export function getPropertyValues( }); } if (property === DatasetCohortColumns.TrueY) { - return indexes.map((index) => { - return dataset.true_y[index]; - }); + const trueYs = dataset.true_y; + if (trueYs) { + return indexes.map((index) => { + return trueYs[index]; + }); + } } if (dataset.predicted_y && dataset.true_y) { return getErrors(property, indexes, dataset, modelType); @@ -62,6 +65,7 @@ function getErrors( ): unknown[] { if ( dataset.predicted_y && + dataset.true_y && !Array.isArray(dataset.true_y) && !Array.isArray(dataset.predicted_y) ) { diff --git a/libs/model-assessment/src/lib/ModelAssessmentDashboard/Controls/IndividualFeatureImportanceView/TextLocalImportancePlots.tsx b/libs/model-assessment/src/lib/ModelAssessmentDashboard/Controls/IndividualFeatureImportanceView/TextLocalImportancePlots.tsx index 2f14c412da..bcccdfdc89 100644 --- a/libs/model-assessment/src/lib/ModelAssessmentDashboard/Controls/IndividualFeatureImportanceView/TextLocalImportancePlots.tsx +++ b/libs/model-assessment/src/lib/ModelAssessmentDashboard/Controls/IndividualFeatureImportanceView/TextLocalImportancePlots.tsx @@ -86,7 +86,7 @@ export class TextLocalImportancePlots extends React.Component