Skip to content

Add annotation plots above intersection bars - #23

Open
edmundmiller wants to merge 6 commits into
mainfrom
feature/annotation-plots
Open

Add annotation plots above intersection bars#23
edmundmiller wants to merge 6 commits into
mainfrom
feature/annotation-plots

Conversation

@edmundmiller

Copy link
Copy Markdown
Owner

Summary

Add support for annotation plots above intersection bars, similar to the ComplexUpset R library functionality. This enables visualization of additional data attributes (like expression levels, p-values, fold changes) alongside set intersection analysis.

Key Features

  • Multiple plot types: boxplot, violin, strip, and bar charts for different data types
  • Flexible API: Dictionary and list-based annotation specifications
  • Full integration: Works with existing sorting, colors, and interactive features
  • Genomic analysis ready: Perfect for expression levels, statistical measures, and categorical annotations
  • Backward compatible: No breaking changes to existing API

Example Usage

import altair_upset as au

# Basic annotation
chart = au.UpSetAltair(
    data=data,
    sets=["condition_A", "condition_B", "condition_C"],
    annotations={
        "expression_level": {"type": "boxplot", "height": 120},
        "fold_change": {"type": "violin", "height": 100}
    }
)

# Multiple genomic annotations
chart = au.UpSetAltair(
    data=genomic_data,
    sets=["treatment_1", "treatment_2", "control"],
    annotations={
        "log2_fc": {"type": "boxplot", "title": "Log2 Fold Change"},
        "p_value": {"type": "strip", "title": "P-Value"},
        "gene_type": {"type": "bar", "title": "Gene Category"}
    }
)

Implementation Details

  • 5 logical commits with clean separation of concerns
  • 22 comprehensive test cases covering all functionality
  • 78% code coverage including edge cases and error handling
  • Full code style compliance with project linting standards

Files Changed

  • altair_upset/annotations.py - New annotation plot generators
  • altair_upset/preprocessing.py - Data aggregation and validation
  • altair_upset/components.py - Chart integration and layout
  • altair_upset/upset.py - Extended main API with annotations parameter
  • altair_upset/__init__.py - Export AnnotationSpec class
  • tests/test_annotations.py - Comprehensive test suite

Test Coverage

✅ All annotation plot types (boxplot, violin, strip, bar)
✅ Genomic use cases (expression, fold change, p-values)
✅ Data handling (missing values, empty intersections)
✅ Integration with existing features (sorting, colors, abbreviations)
✅ Error handling (invalid inputs, edge cases)
✅ Custom specifications and layout alignment
✅ Backward compatibility (all existing tests pass)

🤖 Generated with Claude Code

edmundmiller and others added 6 commits August 23, 2025 17:42
Add comprehensive development documentation including project architecture, essential commands, testing infrastructure, and key dependencies for Claude Code integration.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add preprocess_annotation_data() to aggregate attributes by intersection
- Add create_intersection_summary() for intersection metadata
- Add validate_annotation_attributes() for input validation
- Support preserving original item data for annotation plots
- Handle missing values and edge cases gracefully
- Create AnnotationSpec class for plot configuration
- Implement boxplot, violin, strip, and bar chart annotation types
- Add create_annotation_plot() with support for custom colors and tooltips
- Support flexible annotation specification parsing (dict/list formats)
- Enable color encoding by categorical attributes
- Align annotation plots with main UpSet x-axis for proper layout
- Add integrate_annotation_charts() function for vertical layout management
- Stack annotation charts above intersection bars and main plot
- Maintain proper spacing and alignment between all components
- Support empty annotation lists with fallback to original layout
- Add annotations parameter to UpSetAltair() function with flexible input formats
- Support dict format: {'attribute': {'type': 'boxplot', 'height': 100}}
- Support list format with AnnotationSpec objects
- Integrate annotation processing with existing validation pipeline
- Update UpSetChart class to store annotation data for access
- Maintain full backward compatibility with existing API
- Export AnnotationSpec class for advanced usage
- Add 22 test cases covering all annotation plot types and features
- Test basic annotations: boxplot, violin, strip, bar charts
- Test genomic use cases: expression levels, fold changes, p-values
- Test data handling: missing values, empty intersections, aggregation
- Test integration: sorting, custom colors, abbreviations compatibility  
- Test error handling: invalid attributes, unsupported types
- Test custom specifications and layout alignment
- All tests pass with 78% code coverage
@claude

claude Bot commented Aug 24, 2025

Copy link
Copy Markdown

Claude finished @edmundmiller's task —— View job


PR Review Analysis

I've completed a comprehensive review of this PR that adds annotation plots functionality. Here's my detailed analysis:

Review Checklist

  • Read and understand the new annotation functionality
  • Analyze code quality and best practices
  • Check for potential bugs or issues
  • Assess performance considerations
  • Review security concerns
  • Evaluate test coverage and quality
  • Provide comprehensive feedback

Overall Assessment: Strong Implementation

This is a well-architected feature addition that maintains high code quality standards. The implementation is clean, well-documented, and properly integrated with the existing codebase.

🎯 Strengths

Code Quality & Architecture

  • Excellent separation of concerns: New functionality is properly modularized in dedicated files
  • Clean API design: Flexible annotation specification supports both dict and list formats
  • Consistent with existing patterns: Follows established project conventions and naming
  • Comprehensive documentation: Good docstrings with parameter descriptions and examples
  • Type annotations: Proper typing throughout the codebase

Implementation Details

  • Robust error handling: Good validation of inputs and meaningful error messages
  • Flexible design: Supports multiple plot types (boxplot, violin, strip, bar) with extensibility
  • Data preprocessing: Solid handling of intersection mapping and data aggregation
  • Integration: Seamless integration with existing chart components and sorting

Testing

  • Comprehensive test suite: 22 test cases covering various scenarios
  • Edge case coverage: Tests handle missing values, empty intersections, and invalid inputs
  • Fixture-based approach: Good use of pytest fixtures for genomic and basic data

🔍 Detailed Code Review

altair_upset/annotations.py

Strengths:

  • Clean class design with AnnotationSpec
  • Good abstraction with separate functions for each plot type
  • Proper handling of color encoding and tooltip configuration
  • Flexible parsing function supports multiple input formats

Minor Issues:

  1. Line 259: The jitter calculation (random() - 0.5) * 0.4 uses Vega's random() function which isn't seeded. This could make strip plots non-reproducible.
  2. Line 174: Comment mentions "Altair doesn't have native violin plots" - consider adding a note about the density approximation approach
  3. Line 272: Bar annotation for categorical data might be misleading - it shows counts rather than proportions, which could be confusing when intersection sizes vary greatly

altair_upset/preprocessing.py

Strengths:

  • Good data validation with meaningful error messages
  • Proper handling of missing values
  • Clean intersection ID mapping logic

Minor Issues:

  1. Lines 214-217: The validation logic requires at least 2 non-null values, but some plot types (like bar charts for categories) might work with just 1 value
  2. Line 98: Adding _item_id modifies the data structure - consider using a different approach to track items without mutation

altair_upset/upset.py

Strengths:

  • Clean integration of annotation functionality
  • Comprehensive input validation
  • Backwards compatibility maintained
  • Good parameter documentation

Minor Issues:

  1. Line 235: Storing the entire original dataset in memory for annotations could be memory-intensive for large datasets
  2. Lines 232-240: Annotation preprocessing happens even if annotations is empty after parsing

tests/test_annotations.py

Strengths:

  • Well-structured test suite with good fixtures
  • Tests cover multiple plot types and edge cases
  • Good use of genomic data scenarios

Performance Considerations

Potential Areas:

  1. Memory usage: Storing full original dataset for annotations could be optimized
  2. Data processing: Multiple dataframe operations in preprocessing could be streamlined
  3. Chart rendering: Multiple annotation charts increase Vega-Lite spec size

Recommendations:

  • Consider lazy evaluation for annotation data preprocessing
  • Add optional data sampling for very large datasets
  • Monitor Vega-Lite spec size with multiple annotations

🔒 Security Assessment

Low Risk Profile:

  • No user input injection vulnerabilities identified
  • No file system operations or external network calls
  • Data validation prevents most malformed input issues
  • Uses established Altair/Vega-Lite rendering pipeline

Best Practices:

  • Input validation is comprehensive
  • Error messages are informative but don't leak sensitive info
  • No dynamic code execution

📊 Test Coverage Analysis

Coverage Highlights:

  • ✅ All plot types tested (boxplot, violin, strip, bar)
  • ✅ Multiple annotation specification formats
  • ✅ Error handling and edge cases
  • ✅ Integration with existing features
  • ✅ Genomic use cases covered

Minor Gaps:

  • Performance testing with large datasets
  • Visual regression testing for chart output
  • Memory usage testing

🚀 Recommendations

High Priority:

  1. Strip plot reproducibility: Consider adding a seed parameter or using a different jitter approach
  2. Memory optimization: Implement lazy loading for annotation data in large datasets
  3. Bar chart clarity: Consider adding proportion/percentage options for categorical annotations

Medium Priority:

  1. Add configuration option to limit the number of annotation plots
  2. Consider adding animation/transition support for interactive features
  3. Add more sophisticated color schemes for multiple annotations

Low Priority:

  1. Add export functionality for annotation data
  2. Consider adding annotation-specific styling options
  3. Add support for custom aggregation functions

📝 Summary

This is a high-quality implementation that successfully extends the UpSet plot functionality with a well-designed annotation system. The code follows best practices, maintains backward compatibility, and includes comprehensive testing.

Key Achievements:

  • ✅ Clean, maintainable architecture
  • ✅ Flexible and intuitive API
  • ✅ Comprehensive error handling
  • ✅ Good test coverage
  • ✅ Proper documentation
  • ✅ Genomic analysis use cases supported

The few minor issues identified are optimization opportunities rather than blocking problems. The feature is ready for production use and will be valuable for users analyzing complex biological datasets.

Recommendation: ✅ Approve with minor suggestions

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.

1 participant