Skip to content

3d Visualizations of optimization problems #581

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

shammeer-s
Copy link

@shammeer-s shammeer-s commented Apr 13, 2025

Sandbox Version: These changes are added as a sandbox version of slice_plot. It can be imported using om.sandbox.slice_plot_3d

Summary of changes

  1. slice_plot_3d now supports surface and contour projections.
  2. Introduction of layout_kwargs and make_subplot_kwargs for easier layout and subplot control. Users can adjust figure size, spacing, shared axes, and grid structure effortlessly.
  3. plot_kwargs allows users to customize visual aspects (line color, scatter size, surface colorscale, contour smoothness) for each plot type individually.
  4. Added a new notebook, how_to_slice_plot_3d.ipynb, with detailed examples and use cases to assist with adoption.

Future Improvements

  1. Improved plot headings, refined 3D surface scene settings, customized axis ticks/labels, and subplot titles for clearer grids.
  2. Reducing redundant grid evaluations to improve computational efficiency.

Note: An extensive parameter usage is provided in the attached notebook (Inside the .zip), advanced_slice_plot_3d_usage.zip. Example outputs are also included below in this comment.

- Modularized code into distinct functions for preprocessing, evaluation, and plotting.
- Introduced `_plot_slice` and `_plot_pairwise` to handle different projection types.
- Simplified and optimized logic for generating grid and evaluation points.
- Improved code readability by removing redundant code and separating responsibilities.
…ion components for improved modularity and maintainability.

Added documentation strings for function definition on plot_data.py.
- Added detailed docstrings to improve clarity and usability
- Made minor changes to code structure for better readability and maintainability
@shammeer-s shammeer-s marked this pull request as draft April 13, 2025 18:50
@shammeer-s shammeer-s marked this pull request as ready for review April 13, 2025 18:51
Copy link
Member

@timmens timmens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey,

Thanks for the PR!

Before I start a thorough review of your changes, lets tackle some high-level issues:

  1. Can you move the code from plot_data.py into the slice_plot.py module, unless it is also used in other plotting functions.
  2. Can you re-order the functions such that the function that is exported by the module (slice_plot) is at the beginning, then the private slice plot functions, and lastly the plotting data code.
  3. Can you create a small notebook where you showcase the usage of the new features (this does not need to pushed, you can just upload it in a comment here).

Thanks a lot! If you have any questions, let me know here or on Zulip!

@shammeer-s
Copy link
Author

Hey @timmens,

Thanks for the feedback!

Sure, I’ll move the code from plot_data.py into slice_plot.py as suggested, since it’s not being used elsewhere. I’ll also re-order the functions so that the exported slice_plot function comes first.

I'll work on a small notebook to demonstrate the new features and share it here once it’s ready.

Also, I’ll take this opportunity to improve the modularity of the plotting logic a bit—cleaning it up should make the flow easier to understand.

Let me know if there's anything else I should add or keep in mind!

@shammeer-s shammeer-s marked this pull request as draft April 25, 2025 22:13
Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@shammeer-s shammeer-s marked this pull request as ready for review April 28, 2025 13:57
Copy link

codecov bot commented Apr 29, 2025

Codecov Report

Attention: Patch coverage is 17.22973% with 245 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/optimagic/visualization/slice_plot_3d.py 16.38% 245 Missing ⚠️
Files with missing lines Coverage Δ
src/optimagic/__init__.py 93.33% <100.00%> (ø)
src/optimagic/sandbox.py 100.00% <100.00%> (ø)
src/optimagic/visualization/slice_plot_3d.py 16.38% <16.38%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@timmens timmens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much—this is looking great already! A few things that need to be addressed before we continue:

General

  • Type annotations: Mypy is complaining because there are missing annotations. Could you add argument and return type hints wherever the types are clear? For the exported function interfaces, feel free to silence the error (if you are unsure) with # type: ignore[no-untyped-def].
  • Pre-commit hooks: Ruff is flagging some issues. Please fix those and make sure all pre-commit hooks run and pass before pushing.
  • Tests: Add test_slice_plot_3d.py to cover slice_plot_3d.py (use test_slice_plot.py as a template). Ideally include:
    • End-to-end tests calling slice_plot_3d() with various inputs.
    • Unit tests for each helper function.
  • Code: To gain a better understanding how your code differs from our current slice_plot implementation, could you please align your code with that of slice_plot. Currently you are doing two things at the same time: (1) you are adding the 3D feature, and (2) you are refactoring the slice_plot code. It is hard to focus on (1) when you are also doing (2). For example, the function evaluate_func does not exist in the original implementation, and it is hard for me to see whether you added functionality there.

Visualization comments

These comments arose after looking at the how-to notebook

  • 1D Slice Plot
    • Remove the plot title "Slice Plot".
    • Remove the legend entry "trace 1".
  • 3D Surface Plot (Two parameters)
    • Remove the plot title "Slice Plot".
    • Ensure both axes are fully visible (currently cropped, especially in the lower center).
    • Rename the axes from "x"/"y" to "alpha"/"beta".
  • 2D Contour Plot (Two parameters)
    • Remove the plot title "Slice Plot".
    • Label the axes "alpha" and "beta".
    • Add a color legend so it’s clear which color matches each contour level.
  • Grid View (Multiple parameters)
    • Use a selector to focus on the first three parameters.
    • Once the individual plots are fixed, also ensure:
    • No plot title "Slice Plot".
    • No legend "trace 1".
    • All axes visible in the 3D plots (no cropping).
    • Display parameter names outside the grid—once along the left edge and once along the bottom, similar to sns.pairplot.
  • Behavior change for projection:
    • If projection is a string (or Enum), e.g., "surface":
      • Diagonal: univariate slice plots
      • Lower triangle: 2D/3D plots based on that string
      • Upper triangle: empty
    • If projection is a dictionary {"lower": "surface", "upper": "contour"}:
      • Diagonal: univariate slice plots
      • Lower triangle: 3D surface plots
      • Upper triangle: 2D contour plots
    • I’d recommend parsing projection early into {"lower":…, "upper":…}, where None means no plot (e.g. "surface"{"lower":"surface","upper":None}). Given your implementation the dictionary values can be parsed to the Projection Enum at this point as well.

Thanks a lot! If you have any questions let me know!

@@ -0,0 +1,3 @@
from optimagic.visualization.slice_plot_3d import slice_plot_3d

slice_plot_3d = slice_plot_3d
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
slice_plot_3d = slice_plot_3d
__all__ = ["slice_plot_3d"]

Comment on lines +131 to +133
plot_kwargs = plot_kwargs or {}
make_subplot_kwargs = make_subplot_kwargs or {}
layout_kwargs = layout_kwargs or {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please perform explicit checks for is None.


# Plot utils
class Projection(Enum):
SLICE = auto()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer UNIVARIATE.

Comment on lines +479 to +480
class Projection(Enum):
SLICE = auto()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
class Projection(Enum):
SLICE = auto()
class Projection(str, Enum):
SLICE = "slice"

Same for the other attributes.

else:
raise TypeError(f"Expected str or Projection(Enum), got {type(value)}")

def is_single(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def is_single(self):
def is_univariate(self):

def is_single(self):
return self == Projection.SLICE

def is_multiple(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def is_multiple(self):
def is_bivariate(self):

Comment on lines +82 to +85
• rows, cols computed from a number of parameters and projection
• start_cell='top-left', print_grid=False
• horizontal_spacing=1/(cols*5), vertical_spacing=(1/(max(rows-1,1)))/5
• If projection is contour or surface, `specs` grid matching types are
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use regular markdown bullet points, instead of unicode bullet points.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants