Skip to content

Conversation

Copilot
Copy link

@Copilot Copilot AI commented Sep 23, 2025

Problem

When overlaying Points elements with categorical color mappings, elements with different categorical subsets would incorrectly share color mapper factors, resulting in broken legends and inconsistent color assignments.

This issue manifested in two main scenarios:

  1. Subset categories: When one element contained all categories and another contained only a subset
  2. Disjoint categories: When elements had completely different categorical sets

Example

import holoviews as hv
import pandas as pd

# Create data with different categorical subsets
full_data = pd.DataFrame({'x': [1,2,3,4], 'y': [1,2,3,4], 'cat': ['A','B','C','D']})
subset_data = pd.DataFrame({'x': [5,6], 'y': [5,6], 'cat': ['C','D']})

p1 = hv.Points(full_data, ['x', 'y'], 'cat').opts(color=hv.dim('cat'), show_legend=True)
p2 = hv.Points(subset_data, ['x', 'y'], 'cat').opts(color=hv.dim('cat'), show_legend=True)

# Before fix: p2 incorrectly used factors ['A','B','C','D'] (from p1)
# After fix: p2 correctly uses factors ['C','D'] (from its own data)
overlay = p1 * p2

Root Cause

The issue was in the _apply_transforms method where categorical color mappings (color=hv.dim('category')) were computed. The code was using shared factors from the overlay's combined ranges instead of computing factors from each element's individual data:

# Problematic code:
if range_key in ranges and 'factors' in ranges[range_key]:
    factors = ranges[range_key]['factors']  # Used combined factors from overlay
else:
    factors = util.unique_array(val)

This caused all elements in an overlay to share the same categorical factors (typically from the first element), breaking color mapping consistency.

Solution

Modified the factor computation logic to always use each element's individual data for categorical color mappings:

# Fixed code:
factors = util.unique_array(val)  # Always use element's own data

This ensures each element maintains its own categorical color mapping integrity while preserving existing functionality for non-overlay scenarios.

Changes

  • Modified _apply_transforms method (lines 1888-1897) - Primary fix for color=hv.dim() mappings
  • Modified _get_color_data method (lines 2908-2913) - Secondary fix for color_index based mappings
  • Added comprehensive test suite - New test file covering subset, disjoint, and same-category scenarios

Testing

All scenarios from the original issue now work correctly:

  • ✅ Full dataset vs subset overlay
  • ✅ Completely disjoint categorical sets
  • ✅ Elements with identical categories (compatibility preserved)
  • ✅ Single element plots (no regression)

Fixes #6691


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@droumis droumis changed the title [WIP] Raised in issue #6691: In this issue, two Points elements are created with the color encoded with the color plot option set to the same dimension. One element contains all the categories found in that dimension, the other one only contains a subset.... [WIP] Fix legend when overlaying color-encoded categorical points Sep 23, 2025
@droumis
Copy link
Member

droumis commented Sep 23, 2025

@maximlt @hoxbro , I was curious about the state of github copilot agents and so I'm just testing what is comes up with for issue #6691... just a little experiment

@Copilot Copilot AI changed the title [WIP] Fix legend when overlaying color-encoded categorical points Fix categorical color mapping in overlays for different factor subsets Sep 23, 2025
@Copilot Copilot AI requested a review from droumis September 23, 2025 11:29
Copilot finished work on behalf of droumis September 23, 2025 11:29
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.

Legend is wrongly defined when overlaying color-encoded categorical points
2 participants