Skip to content

Conversation

@Ayushmaan06
Copy link

@Ayushmaan06 Ayushmaan06 commented Mar 12, 2025

Hey @jcharkow !
This PR addresses issue #53 by integrating the feature to plot peptide sequences with matched fragments into the Matplotlib backend interface.
I have followed your instructions from the issue description.
The following changes have been made:

  • Abstract Method in _core.py:
    Added an abstract method in SpectrumPlot class for adding peptide sequences to the plot. This method allows for flexible backend implementations (currently only matplotlib).

  • Matplotlib Backend Implementation:
    Implemented the method for plotting the peptide sequence in the matplotlib backend (file _matplotlib/core.py). This implementation uses a simple text-based approach to display the peptide sequence on the plot.

  • Configuration Option:
    Introduced a new configuration option in SpectrumConfig (in _config.py) called display_peptide_sequence. This option controls whether the peptide sequence should be shown on the plot. By default, this is set to False.

  • Testing:
    Added tests in test_chromatogram.py to ensure that the peptide sequence is properly displayed when the configuration is enabled. Also, tests ensure that when a backend other than matplotlib is used, a NotImplementedError is raised, as expected.

Would appreciate it if you could review and provide any feedback or required changes. Thanks!

Summary by CodeRabbit

  • New Features

    • Enhanced spectrum plot customization with options to display peptide sequences, including configurable font size, colors, and highlight transparency.
    • Improved visualization routines across multiple backends, with integrated peptide sequence annotations in Matplotlib and placeholder support for Bokeh and Plotly.
  • Tests

    • Introduced a dummy plotting implementation to streamline testing and simulate rendering behavior without full functionality.

@coderabbitai
Copy link

coderabbitai bot commented Mar 12, 2025

Walkthrough

This update introduces a new peptide sequence display feature across multiple spectrum plot backends. The changes add an add_peptide_sequence method to the Bokeh, Plotly, and Matplotlib plot classes (with varying implementations), and integrate it into the abstract SpectrumPlot by updating its plot method to accept keyword arguments. The SpectrumConfig class is extended with new attributes controlling peptide sequence display and highlighting. Additionally, several HTML snapshots for Bokeh visualizations have updated identifiers, and a DummySpectrumPlot class has been added to support testing.

Changes

File(s) Change Summary
pyopenms_viz/_bokeh/core.py
pyopenms_viz/_plotly/core.py
Added add_peptide_sequence(peptide_sequence, matched_fragments) method that raises a NotImplementedError for unsupported backends.
pyopenms_viz/_core.py Introduced abstract add_peptide_sequence to SpectrumPlot and updated the plot method to accept **kwargs and conditionally call the peptide sequence method.
pyopenms_viz/_matplotlib/core.py Added methods _create_figure, create_main_plot, add_peptide_sequence, and updated plot for handling peptide sequence rendering with type annotations.
pyopenms_viz/_config.py Extended SpectrumConfig with new attributes: display_peptide_sequence, peptide_sequence_fontsize, peptide_sequence_color, highlight_color, and highlight_alpha.
test/__snapshots__/test_spectrum/*.html Updated multiple HTML snapshots by revising div element IDs, script IDs, document IDs, and root ID mappings for Bokeh visualizations.
test/test_chromatogram.py Added DummySpectrumPlot class with stub implementations for required methods and an overridden plot_peptide_sequence that raises a NotImplementedError.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SpectrumPlot
    participant PlotBackend

    User->>SpectrumPlot: plot(**kwargs)
    SpectrumPlot->>SpectrumPlot: Check config.display_peptide_sequence
    alt Peptide sequence provided
        SpectrumPlot->>PlotBackend: add_peptide_sequence(peptide_sequence, matched_fragments)
        Note right of PlotBackend: Implement or raise NotImplementedError
    else
        SpectrumPlot-->>User: Render standard plot
    end
Loading

Poem

Hoppin' through the code with joyful leaps,
New peptide methods bloom like spring peeps.
Bokeh, Plotly, Matplotlib join the dance,
Configs and snapshots now enhanced by chance.
With each update my whiskers twitch in delight—
A rabbit’s cheer for code that’s shining bright! 🐇

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
pyopenms_viz/_core.py (1)

814-820: Well integrated peptide sequence display logic

The conditional logic properly checks for configuration settings before attempting to display the peptide sequence, providing a clean integration with the existing plotting functionality.

Consider simplifying line 816-817 by removing the redundant None default:

-            peptide_sequence = kwargs.get("peptide_sequence", None)
-            matched_fragments = kwargs.get("matched_fragments", [])
+            peptide_sequence = kwargs.get("peptide_sequence")
+            matched_fragments = kwargs.get("matched_fragments", [])

The get method already returns None by default when the key is not found.

🧰 Tools
🪛 Ruff (0.8.2)

816-816: Use kwargs.get("peptide_sequence") instead of kwargs.get("peptide_sequence", None)

Replace kwargs.get("peptide_sequence", None) with kwargs.get("peptide_sequence")

(SIM910)

pyopenms_viz/_matplotlib/core.py (1)

651-669: Refactor nested if statements (SIM102).

Currently, lines 664-665 use nested conditionals. Consolidate these into one statement:

 if self._config.display_peptide_sequence:
-    if "sequence" in self.data.columns:
-        self.add_peptide_sequence(self.data["sequence"], self.data["matched_fragments"])
+    if "sequence" in self.data.columns and "matched_fragments" in self.data.columns:
+        self.add_peptide_sequence(
+            self.data["sequence"],
+            self.data["matched_fragments"]
+        )
🧰 Tools
🪛 Ruff (0.8.2)

664-665: Use a single if statement instead of nested if statements

(SIM102)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 40549e8 and 974d5fd.

⛔ Files ignored due to path filters (13)
  • test/__snapshots__/test_spectrum/test_mirror_spectrum[ms_matplotlib].png is excluded by !**/*.png
  • test/__snapshots__/test_spectrum/test_spectrum_binning[ms_matplotlib-kwargs0].png is excluded by !**/*.png
  • test/__snapshots__/test_spectrum/test_spectrum_binning[ms_matplotlib-kwargs1].png is excluded by !**/*.png
  • test/__snapshots__/test_spectrum/test_spectrum_binning[ms_matplotlib-kwargs2].png is excluded by !**/*.png
  • test/__snapshots__/test_spectrum/test_spectrum_binning[ms_matplotlib-kwargs3].png is excluded by !**/*.png
  • test/__snapshots__/test_spectrum/test_spectrum_binning[ms_matplotlib-kwargs4].png is excluded by !**/*.png
  • test/__snapshots__/test_spectrum/test_spectrum_plot[ms_matplotlib-kwargs0].png is excluded by !**/*.png
  • test/__snapshots__/test_spectrum/test_spectrum_plot[ms_matplotlib-kwargs1].png is excluded by !**/*.png
  • test/__snapshots__/test_spectrum/test_spectrum_plot[ms_matplotlib-kwargs2].png is excluded by !**/*.png
  • test/__snapshots__/test_spectrum/test_spectrum_plot[ms_matplotlib-kwargs3].png is excluded by !**/*.png
  • test/__snapshots__/test_spectrum/test_spectrum_with_annotations[ms_matplotlib-kwargs0].png is excluded by !**/*.png
  • test/__snapshots__/test_spectrum/test_spectrum_with_annotations[ms_matplotlib-kwargs1].png is excluded by !**/*.png
  • test/__snapshots__/test_spectrum/test_spectrum_with_annotations[ms_matplotlib-kwargs2].png is excluded by !**/*.png
📒 Files selected for processing (19)
  • pyopenms_viz/_bokeh/core.py (2 hunks)
  • pyopenms_viz/_config.py (1 hunks)
  • pyopenms_viz/_core.py (3 hunks)
  • pyopenms_viz/_matplotlib/core.py (2 hunks)
  • pyopenms_viz/_plotly/core.py (1 hunks)
  • test/__snapshots__/test_spectrum/test_mirror_spectrum[ms_bokeh].html (1 hunks)
  • test/__snapshots__/test_spectrum/test_spectrum_binning[ms_bokeh-kwargs0].html (1 hunks)
  • test/__snapshots__/test_spectrum/test_spectrum_binning[ms_bokeh-kwargs1].html (1 hunks)
  • test/__snapshots__/test_spectrum/test_spectrum_binning[ms_bokeh-kwargs2].html (1 hunks)
  • test/__snapshots__/test_spectrum/test_spectrum_binning[ms_bokeh-kwargs3].html (1 hunks)
  • test/__snapshots__/test_spectrum/test_spectrum_binning[ms_bokeh-kwargs4].html (1 hunks)
  • test/__snapshots__/test_spectrum/test_spectrum_plot[ms_bokeh-kwargs0].html (1 hunks)
  • test/__snapshots__/test_spectrum/test_spectrum_plot[ms_bokeh-kwargs1].html (1 hunks)
  • test/__snapshots__/test_spectrum/test_spectrum_plot[ms_bokeh-kwargs2].html (1 hunks)
  • test/__snapshots__/test_spectrum/test_spectrum_plot[ms_bokeh-kwargs3].html (1 hunks)
  • test/__snapshots__/test_spectrum/test_spectrum_with_annotations[ms_bokeh-kwargs0].html (1 hunks)
  • test/__snapshots__/test_spectrum/test_spectrum_with_annotations[ms_bokeh-kwargs1].html (1 hunks)
  • test/__snapshots__/test_spectrum/test_spectrum_with_annotations[ms_bokeh-kwargs2].html (1 hunks)
  • test/test_chromatogram.py (2 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
pyopenms_viz/_core.py

816-816: Use kwargs.get("peptide_sequence") instead of kwargs.get("peptide_sequence", None)

Replace kwargs.get("peptide_sequence", None) with kwargs.get("peptide_sequence")

(SIM910)

pyopenms_viz/_matplotlib/core.py

664-665: Use a single if statement instead of nested if statements

(SIM102)

🔇 Additional comments (41)
pyopenms_viz/_plotly/core.py (1)

622-623: New method signature looks good but is not yet implemented for Plotly

The add_peptide_sequence method has been added to maintain a consistent interface across different backend implementations, correctly raising NotImplementedError since this functionality is only implemented for Matplotlib as mentioned in the PR summary.

pyopenms_viz/_bokeh/core.py (2)

2-2: Good imports update to support new method

The typing import has been properly updated to include List and Tuple for the type annotations needed in the new method.


544-545: New method signature looks good but is not yet implemented for Bokeh

The add_peptide_sequence method has been added to maintain a consistent interface across different backend implementations, correctly raising NotImplementedError as mentioned in the PR summary.

test/__snapshots__/test_spectrum/test_spectrum_binning[ms_bokeh-kwargs4].html (2)

21-24: Updated test snapshot IDs are expected

The changes to element IDs are expected when regenerating test snapshots after code changes. These are automatically generated by the testing framework and don't require specific review.


32-33: Updated document references are expected

The modifications to document references and render items are consistent with the updated element IDs above and are expected when regenerating test snapshots.

test/__snapshots__/test_spectrum/test_spectrum_with_annotations[ms_bokeh-kwargs0].html (3)

21-21: Updated test snapshot IDs are expected

The changes to element IDs are expected when regenerating test snapshots after code changes. These are automatically generated by the testing framework and don't require specific review.


23-24: Updated script references are expected

The modifications to script ID and JSON content are consistent with the updated element IDs and are expected when regenerating test snapshots.


32-33: Updated document references are expected

The modifications to document references and render items are consistent with the updated element IDs above and are expected when regenerating test snapshots.

test/__snapshots__/test_spectrum/test_spectrum_with_annotations[ms_bokeh-kwargs1].html (1)

21-21: Changes to element IDs and data references look appropriate.

These changes update Bokeh element and data IDs which appear to be regenerated snapshots after implementing the new peptide sequence feature. The modifications maintain the proper structure required for Bokeh visualization rendering.

Also applies to: 23-24, 32-33

test/__snapshots__/test_spectrum/test_spectrum_binning[ms_bokeh-kwargs1].html (1)

21-21: Updated Bokeh element and data IDs look correct.

Similar to the previous file, these snapshot changes are expected when regenerating test files after implementing the new peptide sequence feature. The ID updates maintain proper Bokeh rendering structure.

Also applies to: 23-24, 32-33

test/__snapshots__/test_spectrum/test_spectrum_plot[ms_bokeh-kwargs2].html (1)

21-21: Element and data ID updates maintain proper Bokeh structure.

These are the expected changes when regenerating test snapshots after implementing the new peptide sequence feature. The modifications correctly maintain the relationship between DOM elements and Bokeh data references.

Also applies to: 23-24, 32-33

pyopenms_viz/_config.py (1)

360-364: New configuration options for peptide sequence display look good.

The added configuration options properly support the new peptide sequence display feature:

  • display_peptide_sequence is disabled by default (good for backward compatibility)
  • Font size, colors, and highlighting alpha values have sensible defaults
  • The naming convention is consistent with the rest of the codebase

These additions align well with the PR objective to add peptide sequence visualization capabilities.

test/__snapshots__/test_spectrum/test_spectrum_binning[ms_bokeh-kwargs0].html (3)

21-21: Regenerated Bokeh div element identifiers match updated implementation.

The HTML div element has been updated with new identifiers, which is expected when the underlying Bokeh implementation changes.


23-24: Updated JSON script element with new identifiers.

The script element containing the Bokeh visualization data has been appropriately updated with new IDs.


32-33: JavaScript references correctly updated to match new element IDs.

The document embedding code has been properly synchronized with the new IDs defined above.

test/test_chromatogram.py (4)

5-6: Good addition of headless Matplotlib backend.

Setting the Agg backend prevents GUI-related errors when running tests in environments without display capabilities.


59-71: Well-structured DummySpectrumPlot initialization.

The class correctly implements a lightweight test double by manually setting only the essential attributes needed for testing rather than calling the parent constructor. The explicit comment about initialization strategy is helpful.

I particularly like that you're enabling the display_peptide_sequence flag in the dummy config to ensure the method will be called during tests.


96-107: Good implementation of test double pattern for renderer.

The nested DummyRenderer class efficiently simulates the behavior of a real renderer without actual rendering. This approach allows for testing the interaction with renderers without dependencies on the actual rendering implementation.


152-154: Appropriate NotImplementedError for unsupported backend.

The plot_peptide_sequence method correctly raises a NotImplementedError with a clear message, which aligns with the PR objective to test behavior when a backend other than Matplotlib is used.

test/__snapshots__/test_spectrum/test_spectrum_plot[ms_bokeh-kwargs1].html (3)

21-21: Bokeh div element correctly updated with new identifiers.

The div element has been updated with new identifiers, which is necessary to match the current implementation.


23-24: JSON data script updated with new identifiers.

The script tag containing visualization data has been properly updated with new identifiers.


32-33: JavaScript initialization correctly uses updated element references.

The embed_document function properly references the new script and div IDs, maintaining synchronization between the HTML structure and JavaScript.

test/__snapshots__/test_spectrum/test_spectrum_with_annotations[ms_bokeh-kwargs2].html (3)

21-21: Div element updated with appropriate new identifiers.

The HTML div has been updated with new identifiers to match the current implementation.


23-24: JSON data script element properly updated.

The script containing visualization data has been updated with appropriate new identifiers.


32-33: JavaScript element references correctly synchronized.

The document initialization code has been properly updated to reference the new identifiers.

pyopenms_viz/_core.py (2)

692-704: Well implemented abstract method for peptide sequence visualization

The addition of the add_peptide_sequence abstract method provides a clear interface for subclasses to implement peptide sequence visualization, with well-documented parameters and purpose.


764-764: Good modification to accept additional parameters

Updating the plot method signature to accept **kwargs is a flexible approach that allows passing additional data to specialized plotting functions.

test/__snapshots__/test_spectrum/test_spectrum_binning[ms_bokeh-kwargs3].html (1)

21-33: Updated test snapshot IDs

The changes to element IDs and references in the test snapshot file are consistent with the implementation of the new feature. These updates are expected when regenerating test snapshots after code changes.

test/__snapshots__/test_spectrum/test_spectrum_plot[ms_bokeh-kwargs0].html (1)

21-33: Updated test snapshot IDs

The changes to element IDs and references in the test snapshot file are consistent with the implementation of the new feature. These updates are expected when regenerating test snapshots after code changes.

test/__snapshots__/test_spectrum/test_spectrum_plot[ms_bokeh-kwargs3].html (1)

21-33: Updated test snapshot IDs

The changes to element IDs and references in the test snapshot file are consistent with the implementation of the new feature. These updates are expected when regenerating test snapshots after code changes.

test/__snapshots__/test_spectrum/test_mirror_spectrum[ms_bokeh].html (3)

21-21: No issues found.

This updated div element ID and data-root-id appear consistent with the new Bokeh embedding references.


23-24: No issues found.

The updated JSON script references for Bokeh rendering look correct.


32-33: No issues found.

These revised references to the new script ID and render items align with the updated Bokeh document IDs.

pyopenms_viz/_matplotlib/core.py (5)

2-2: New import for typed hints is consistent.

Importing List and Tuple supports better type annotations in the new method signatures.


582-582: Docstring update acknowledged.

No functional changes introduced here; the updated docstring maintains clarity.


586-599: Figure creation logic looks good.

This _create_figure override cleanly handles fallback cases for width/height.


600-614: Main plot rendering is well-organized.

Using a line renderer to draw the spectrum data is appropriate here.


615-649: Peptide sequence addition is well-structured.

The method correctly places the sequence text above the main plot and highlights matched fragments. Consider boundary validation if negative (start, end) indices might occur in certain edge cases, though it's likely safe for normal usage.

test/__snapshots__/test_spectrum/test_spectrum_binning[ms_bokeh-kwargs2].html (3)

21-21: No issues found.

The updated div element and data-root-id match the new Bokeh document structure.


23-24: No issues found.

The JSON script ID update appears valid for the snapshot test.


32-33: No issues found.

References to the new document and root IDs are consistent with the updated embed workflow.

Comment on lines +59 to +154
# Dummy backend to test missing peptide sequence implementation
class DummySpectrumPlot(SpectrumPlot):
def __init__(self, data):
# Instead of calling super().__init__(data) (which verifies required columns),
# we manually set minimal attributes needed to pass initialization.
self.data = data.copy()
# Set dummy column values so that _verify_column doesn't raise errors.
self.x = "dummy"
self.y = "dummy"
self.by = None
# Provide a dummy config with display_peptide_sequence enabled.
self._config = type("dummy_config", (), {"display_peptide_sequence": True})()

def plot(self):
pass

def load_config(self, **kwargs):
pass

def _check_and_aggregate_duplicates(self):
pass

def _prepare_data(self, data):
return data

def _create_tooltips(self, entries, index):
return {}, {}

def _get_annotations(self, data, x, y):
return [], [], [], []

def convert_for_line_plots(self, data, x, y):
return data

def _get_colors(self, data, kind):
return "blue"

def get_line_renderer(self, data, by=None, color=None, config=None):
# Return dummy object with required methods.
class DummyRenderer:
def generate(self, tooltips, custom_hover_data):
# Return a dummy canvas with a gca() method.
class DummyAxes:
def gca(self):
return self
return DummyAxes()
def _add_annotations(self, canvas, texts, xs, ys, colors):
pass
return DummyRenderer()

# Provide stubs for all abstract methods from SpectrumPlot:
def _add_bounding_box_drawer(self):
pass

def _add_bounding_vertical_drawer(self):
pass

def _add_legend(self, legend):
pass

def _add_tooltips(self, tooltips, custom_hover_data):
pass

def _create_figure(self):
return None

def _load_extension(self):
pass

def _modify_x_range(self, x_range, padding=None):
pass

def _modify_y_range(self, y_range, padding=None):
pass

def _update_plot_aes(self):
pass

def generate(self, tooltips, custom_hover_data):
return None

def get_scatter_renderer(self, *args, **kwargs):
return None

def get_vline_renderer(self, *args, **kwargs):
return None

def plot_x_axis_line(self, canvas, line_width=2):
pass

def show_default(self):
pass

# Abstract method: raise error since it's not supported in this dummy backend.
def plot_peptide_sequence(self, ax, data):
raise NotImplementedError("Dummy backend does not support peptide sequence plotting")
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

❓ Verification inconclusive

Consider adding a test that verifies the NotImplementedError is raised.

While the DummySpectrumPlot class is well implemented, I don't see an actual test that uses it to verify the NotImplementedError is raised when a non-Matplotlib backend is used. This would complete the testing of the feature described in the PR objectives.


🏁 Script executed:

#!/bin/bash
# Search for tests using DummySpectrumPlot to verify NotImplementedError
rg "DummySpectrumPlot" --type=python -A 10 -B 5 --no-heading

Length of output: 91


Action Required: Add a Test for NotImplementedError in DummySpectrumPlot

It appears that no test currently verifies that the plot_peptide_sequence method in DummySpectrumPlot raises the expected NotImplementedError. Please add a test that imports DummySpectrumPlot, calls its plot_peptide_sequence method (using a dummy axis and data as needed), and asserts that the NotImplementedError with the message "Dummy backend does not support peptide sequence plotting" is raised.

  • Verify in your test suite that:
    • The dummy instance is created correctly.
    • Calling plot_peptide_sequence on this instance triggers a NotImplementedError.

Copy link
Collaborator

@jcharkow jcharkow left a comment

Choose a reason for hiding this comment

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

Good start! This is a challenging PR since the Pyopenms_viz codebase can be difficult
to understand for new developers due to its many layers of abstraction. Please see comments above.

It cannot find where you placed the tests for the sequence plot? Also it seems that you modified a lot of the snapshots and the plots generated seem wonky (e.g. look at matplotlib .png files). The point of snapshot tests not to modify the snapshots as a failing snapshot means that the code is broken.

I think some of the issues of the failing tests are due to you implementing a new plot() function for matplotlibspectrum. I would recommend abstracting the plot() functionality to _core.py as suggested above.

Comment on lines -544 to -546
"""
Class for assembling a Bokeh spectrum plot
"""
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is this deleted?

"""
Class for assembling a Bokeh spectrum plot
"""
def add_peptide_sequence(self, peptide_sequence: str, matched_fragments: List[Tuple[int, int]]):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add a docstring here for good practice. Can be based on the docstring below and explain this is not implemented..

Class for assembling a Bokeh spectrum plot
"""
def add_peptide_sequence(self, peptide_sequence: str, matched_fragments: List[Tuple[int, int]]):
raise NotImplementedError("Not implemented for Bokeh")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Be a bit more descriptive. Something like. "Plotting Peptide Sequences is not supported for the Bokeh backend"

Comment on lines +814 to +819
# Add peptide sequence if configured
if hasattr(self._config, "display_peptide_sequence") and self._config.display_peptide_sequence:
peptide_sequence = kwargs.get("peptide_sequence", None)
matched_fragments = kwargs.get("matched_fragments", [])
if peptide_sequence:
self.add_peptide_sequence(peptide_sequence, matched_fragments)
Copy link
Collaborator

Choose a reason for hiding this comment

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

These variables should be stored automatically in the object. Thus you should be able to reference them using self.peptide_sequence and self.matched_fragments. This will remove the need for kwargs

Comment on lines +586 to +599
def _create_figure(self):
if self.width is None or self.height is None:
self.fig, self.ax = plt.subplots()
else:
self.fig, self.ax = plt.subplots(figsize=(self.width / 100, self.height / 100), dpi=100)

self.ax.set_title(self.title)
self.ax.set_xlabel(self.xlabel)
self.ax.set_ylabel(self.ylabel)

# Ensure `self.canvas` references the Axes, not the Figure
self.canvas = self.ax
return self.ax

Copy link
Collaborator

Choose a reason for hiding this comment

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

This method is likely not needed as there is already this functionality in the MATPLOTLIBPLOT class

Comment on lines +600 to +613
def create_main_plot(self):
"""
Draw the main spectrum (e.g., peaks) on self.ax.
"""
# Example: use a line plot for the spectrum
linePlot = self.get_line_renderer(
data=self.data,
x=self._config.x,
y=self._config.y,
config=self._config,
canvas=self.canvas,
)
ax = linePlot.generate(None, None)
return ax
Copy link
Collaborator

Choose a reason for hiding this comment

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

I see that you structure this after the peakMap which is a little bit of an exception compared to other plots. Some of this can be abstracted more to prevent repeated code. I would recommend removing this function.

Comment on lines +657 to +668
if self.canvas is None:
self.canvas = self._create_figure()

# Create the main spectrum plot
self.ax = self.create_main_plot()

# Plot peptide sequence if set in config
if self._config.display_peptide_sequence:
if "sequence" in self.data.columns:
self.add_peptide_sequence(self.data["sequence"], self.data["matched_fragments"])

return self.ax
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would be best to add this instead to the _core.py SpectrumPlot's plot() function so that it can be shared across backends. I know only matplotlib is supported for now but it might be supported with other backends in the future.

)
return df
def add_peptide_sequence(self, peptide_sequence: str, matched_fragments: List[Tuple[int, int]]):
raise NotImplementedError("Not implemented for Plotly")
Copy link
Collaborator

Choose a reason for hiding this comment

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

See above add docstring and make the NotImplementedErrror more descriptive

Comment on lines +58 to +154

# Dummy backend to test missing peptide sequence implementation
class DummySpectrumPlot(SpectrumPlot):
def __init__(self, data):
# Instead of calling super().__init__(data) (which verifies required columns),
# we manually set minimal attributes needed to pass initialization.
self.data = data.copy()
# Set dummy column values so that _verify_column doesn't raise errors.
self.x = "dummy"
self.y = "dummy"
self.by = None
# Provide a dummy config with display_peptide_sequence enabled.
self._config = type("dummy_config", (), {"display_peptide_sequence": True})()

def plot(self):
pass

def load_config(self, **kwargs):
pass

def _check_and_aggregate_duplicates(self):
pass

def _prepare_data(self, data):
return data

def _create_tooltips(self, entries, index):
return {}, {}

def _get_annotations(self, data, x, y):
return [], [], [], []

def convert_for_line_plots(self, data, x, y):
return data

def _get_colors(self, data, kind):
return "blue"

def get_line_renderer(self, data, by=None, color=None, config=None):
# Return dummy object with required methods.
class DummyRenderer:
def generate(self, tooltips, custom_hover_data):
# Return a dummy canvas with a gca() method.
class DummyAxes:
def gca(self):
return self
return DummyAxes()
def _add_annotations(self, canvas, texts, xs, ys, colors):
pass
return DummyRenderer()

# Provide stubs for all abstract methods from SpectrumPlot:
def _add_bounding_box_drawer(self):
pass

def _add_bounding_vertical_drawer(self):
pass

def _add_legend(self, legend):
pass

def _add_tooltips(self, tooltips, custom_hover_data):
pass

def _create_figure(self):
return None

def _load_extension(self):
pass

def _modify_x_range(self, x_range, padding=None):
pass

def _modify_y_range(self, y_range, padding=None):
pass

def _update_plot_aes(self):
pass

def generate(self, tooltips, custom_hover_data):
return None

def get_scatter_renderer(self, *args, **kwargs):
return None

def get_vline_renderer(self, *args, **kwargs):
return None

def plot_x_axis_line(self, canvas, line_width=2):
pass

def show_default(self):
pass

# Abstract method: raise error since it's not supported in this dummy backend.
def plot_peptide_sequence(self, ax, data):
raise NotImplementedError("Dummy backend does not support peptide sequence plotting")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this needed? Could you just test one of the backends where it is not supported?

@Ayushmaan06
Copy link
Author

Hey @jcharkow ,

I hope you're doing well. I wanted to let you know that while I was working on the peptide sequence plotting updates, I was at college and didn’t realize I was working on a different fork . I only noticed this after completing the work.
Could you please take a look at the new PR #67 that reflects all these changes?
I appreciate your understanding and any feedback you might have.

Thank you,

@jcharkow jcharkow self-requested a review March 14, 2025 21:50
@jcharkow jcharkow closed this Mar 14, 2025
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