Skip to content

Commit

Permalink
Merge pull request #43 from MSDLLCpapers/plotting
Browse files Browse the repository at this point in the history
Added MDS plot
  • Loading branch information
kstone40 authored Aug 22, 2024
2 parents dea7b8c + d7713a0 commit 234d287
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
### Added
- Default values for NParEGO scalarization_weights
- SHAP PDP ICE plots now work with categorical values
- Added scikit-learn to dependencies, for MDS
- Added MDS plot

### Modified
- SHAP PDP ICE plots must now have color and x-axis indices that are distinct
Expand Down
1 change: 1 addition & 0 deletions obsidian/campaign/campaign.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ def add_data(self, df: pd.DataFrame):
def clear_data(self):
"""Clears campaign data"""
self.data = pd.DataFrame()
self.iter = 0

@property
def optimizer(self) -> Optimizer:
Expand Down
50 changes: 50 additions & 0 deletions obsidian/plotting/plotly.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,61 @@

import plotly.graph_objects as go
from plotly.graph_objects import Figure
from sklearn.manifold import MDS

import pandas as pd
import numpy as np


def MDS_plot(campaign: Campaign) -> Figure:
"""
Creates a Multi-Dimensional Scaling (MDS) plot of the campaign data,
colored by iteration.
This plot is helpful to visualize the convergence of the optimizer on a 2D plane.
Args:
campaign (Campaign): The campaign object containing the data.
Returns:
fig (Figure): The MDS plot
"""
mds = MDS(n_components=2)
X_mds = mds.fit_transform(campaign.X_space.encode(campaign.X))

iter_max = campaign.data['Iteration'].max()
iter_vals = campaign.data['Iteration'].values

if campaign.data['Iteration'].nunique() == 1:
iter_vals = np.zeros_like(iter_vals)
iter_max = 0
cbar = None
else:
cbar = dict(title=dict(text='Iteration', font=dict(size=10)))

fig = go.Figure()

fig.add_trace(go.Scatter(x=X_mds[:, 0], y=X_mds[:, 1],
mode='markers',
name='Observations',
marker={'color': iter_vals, 'size': 10,
'cmax': iter_max, 'cmin': 0,
'colorscale': [[0, obsidian_colors.rich_blue],
[0.5, obsidian_colors.teal],
[1, obsidian_colors.lemon]],
'colorbar': cbar
},
showlegend=False
))

fig.update_xaxes(title_text='Component 1')
fig.update_yaxes(title_text='Component 2')
fig.update_layout(template='ggplot2', title='Multi-Dimensional Scaling (MDS) Plot',
autosize=False, height=400, width=500)

return fig


def parity_plot(optimizer: Optimizer,
f_transform: bool = False,
response_id: int = 0) -> Figure:
Expand Down
16 changes: 15 additions & 1 deletion obsidian/tests/test_plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
factor_plot,
surface_plot,
visualize_inputs,
optim_progress
optim_progress,
MDS_plot
)

from obsidian.objectives import Scalar_WeightedSum
Expand Down Expand Up @@ -75,6 +76,19 @@ def test_optim_progress_plot():
obj = Scalar_WeightedSum(weights=[1, 1])
campaign.set_objective(obj)
fig = optim_progress(campaign, X_suggest=X_suggest)


@pytest.mark.fast
def test_MDS_plot():
# Test with default data
fig = MDS_plot(campaign)

# Test with no iteration data
data = campaign.data
data = data.drop(columns='Iteration')
campaign.clear_data()
campaign.add_data(data)
fig = MDS_plot(campaign)


if __name__ == '__main__':
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ sphinx = { version = "^7.3.7", optional = true}
myst-parser = { version = "^3.0.1", optional = true}
pydata-sphinx-theme = { version = "^0.15.4", optional = true}
linkify-it-py = { version = "^2.0.3", optional = true}
scikit-learn = "^1.5.1"


[tool.poetry.extras]
Expand Down

0 comments on commit 234d287

Please sign in to comment.