From bf0f58faaeda095781c10fa3ef98a5add533069a Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Sat, 29 Nov 2025 23:16:15 +0000 Subject: [PATCH] feat(plotly): implement heatmap-correlation Add correlation matrix heatmap implementation for plotly library - Creates interactive heatmap with hover tooltips - Shows correlation values in cells with configurable formatting - Supports upper triangle masking option - Uses RdBu colorscale by default for clear positive/negative distinction - Includes proper input validation for numeric columns Generated with Claude Code Co-Authored-By: Claude --- .../heatmap/heatmap-correlation/default.py | 198 ++++++++++++++++++ specs/heatmap-correlation.md | 54 +++++ 2 files changed, 252 insertions(+) create mode 100644 plots/plotly/heatmap/heatmap-correlation/default.py create mode 100644 specs/heatmap-correlation.md diff --git a/plots/plotly/heatmap/heatmap-correlation/default.py b/plots/plotly/heatmap/heatmap-correlation/default.py new file mode 100644 index 00000000000..b3a393f79cd --- /dev/null +++ b/plots/plotly/heatmap/heatmap-correlation/default.py @@ -0,0 +1,198 @@ +""" +heatmap-correlation: Correlation Matrix Heatmap +Library: plotly +""" + +import plotly.graph_objects as go +import pandas as pd +import numpy as np +from typing import TYPE_CHECKING, Optional, Tuple + +if TYPE_CHECKING: + from plotly.graph_objects import Figure + + +def create_plot( + data: pd.DataFrame, + figsize: Optional[Tuple[float, float]] = None, + cmap: Optional[str] = None, + annot: bool = True, + fmt: str = '.2f', + mask_upper: bool = False, + vmin: float = -1.0, + vmax: float = 1.0, + title: str = 'Correlation Matrix', + **kwargs +) -> go.Figure: + """ + Create a heatmap visualization of the correlation matrix for numerical columns in a dataset. + + Args: + data: Input DataFrame with at least 2 numeric columns + figsize: Figure size in inches (converted to pixels for plotly) + cmap: Color map for the heatmap (plotly uses colorscale) + annot: Show correlation values in cells + fmt: Format string for annotations + mask_upper: Mask the upper triangle for cleaner display + vmin: Minimum value for color scale + vmax: Maximum value for color scale + title: Plot title + **kwargs: Additional parameters + + Returns: + Plotly Figure object + + Raises: + ValueError: If data is empty or has fewer than 2 numeric columns + + Example: + >>> data = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}) + >>> fig = create_plot(data) + """ + # Input validation + if data.empty: + raise ValueError("Data cannot be empty") + + # Select only numeric columns + numeric_data = data.select_dtypes(include=[np.number]) + + if numeric_data.shape[1] < 2: + raise ValueError(f"Data must have at least 2 numeric columns. Found: {numeric_data.shape[1]}") + + # Calculate correlation matrix + corr_matrix = numeric_data.corr() + + # Apply upper triangle mask if requested + if mask_upper: + mask = np.triu(np.ones_like(corr_matrix, dtype=bool), k=1) + corr_display = corr_matrix.copy() + corr_display[mask] = np.nan + else: + corr_display = corr_matrix + + # Prepare text annotations + if annot: + # Format correlation values for display + text_values = [] + for i in range(len(corr_display)): + row_text = [] + for j in range(len(corr_display.columns)): + if pd.isna(corr_display.iloc[i, j]): + row_text.append('') + else: + row_text.append(f'{corr_display.iloc[i, j]:{fmt}}') + text_values.append(row_text) + else: + text_values = None + + # Set colorscale (default to RdBu_r which is similar to coolwarm) + if cmap is None: + colorscale = 'RdBu' + else: + # Map common matplotlib/seaborn colormap names to plotly equivalents + colormap_mapping = { + 'coolwarm': 'RdBu', + 'seismic': 'RdBu', + 'bwr': 'RdBu', + 'viridis': 'Viridis', + 'plasma': 'Plasma', + 'inferno': 'Inferno', + 'magma': 'Magma', + 'cividis': 'Cividis', + 'turbo': 'Turbo', + 'twilight': 'Twilight' + } + colorscale = colormap_mapping.get(cmap, cmap) + + # Create heatmap + fig = go.Figure(data=go.Heatmap( + z=corr_display.values, + x=corr_display.columns.tolist(), + y=corr_display.index.tolist(), + text=text_values, + texttemplate='%{text}' if annot else None, + textfont={'size': 10}, + colorscale=colorscale, + zmin=vmin, + zmax=vmax, + colorbar=dict( + title='Correlation', + tickmode='linear', + tick0=vmin, + dtick=0.5, + len=0.87, + thickness=15 + ), + hoverongaps=False, + hovertemplate='%{x} - %{y}
Correlation: %{z:.2f}' + )) + + # Set figure size + if figsize is not None: + width = int(figsize[0] * 100) # Convert inches to pixels (roughly) + height = int(figsize[1] * 100) + else: + width = 1000 # Default width + height = 800 # Default height + + # Update layout + fig.update_layout( + title=dict( + text=title, + x=0.5, + xanchor='center', + font=dict(size=16) + ), + xaxis=dict( + title='', + tickangle=45, + side='bottom', + showgrid=False, + tickfont=dict(size=11) + ), + yaxis=dict( + title='', + showgrid=False, + tickfont=dict(size=11), + autorange='reversed' # To match typical correlation matrix orientation + ), + width=width, + height=height, + template='plotly_white', + margin=dict(l=100, r=100, t=100, b=100) + ) + + return fig + + +if __name__ == '__main__': + # Sample data for testing + np.random.seed(42) + n_samples = 100 + + # Create sample data with some correlations + data = pd.DataFrame({ + 'Temperature': np.random.normal(25, 5, n_samples), + 'Humidity': np.random.normal(60, 10, n_samples), + 'Pressure': np.random.normal(1013, 20, n_samples), + 'Wind_Speed': np.random.normal(10, 3, n_samples), + 'Rainfall': np.random.exponential(5, n_samples) + }) + + # Add some correlations + data['Solar_Radiation'] = data['Temperature'] * 1.5 + np.random.normal(0, 2, n_samples) + data['Heat_Index'] = data['Temperature'] * 0.8 + data['Humidity'] * 0.3 + np.random.normal(0, 3, n_samples) + + # Create plot + fig = create_plot( + data, + figsize=(10, 8), + cmap='coolwarm', + annot=True, + fmt='.2f', + title='Weather Variables Correlation Matrix' + ) + + # Save - ALWAYS use 'plot.png'! + fig.write_image('plot.png', width=1600, height=900, scale=2) + print("Plot saved to plot.png") \ No newline at end of file diff --git a/specs/heatmap-correlation.md b/specs/heatmap-correlation.md new file mode 100644 index 00000000000..feee5839205 --- /dev/null +++ b/specs/heatmap-correlation.md @@ -0,0 +1,54 @@ +# heatmap-correlation: Correlation Matrix Heatmap + + + +**Spec Version:** 1.0.0 + +## Description + +Create a heatmap visualization of the correlation matrix for numerical columns in a dataset. This plot shows the Pearson correlation coefficients between all pairs of numeric variables, helping identify relationships and dependencies between features in multivariate data. + +## Data Requirements + +- **data**: A DataFrame containing at least 2 numeric columns for correlation calculation + +## Optional Parameters + +- `figsize`: Figure size in inches (type: tuple, default: (10, 8)) +- `cmap`: Color map for the heatmap (type: str, default: 'coolwarm' or library default) +- `annot`: Show correlation values in cells (type: bool, default: True) +- `fmt`: Format string for annotations (type: str, default: '.2f') +- `mask_upper`: Mask the upper triangle for cleaner display (type: bool, default: False) +- `vmin`: Minimum value for color scale (type: float, default: -1.0) +- `vmax`: Maximum value for color scale (type: float, default: 1.0) +- `title`: Plot title (type: str, default: 'Correlation Matrix') + +## Quality Criteria + +- [ ] Heatmap displays correlation values for all numeric column pairs +- [ ] Color scale clearly differentiates positive (warm) and negative (cool) correlations +- [ ] Correlation values are displayed in each cell with 2 decimal precision +- [ ] Column and row labels are readable and not overlapping +- [ ] Color bar shows the correlation scale from -1 to 1 +- [ ] Figure has appropriate aspect ratio (square or near-square for correlation matrix) +- [ ] Diagonal values show perfect correlation (1.0) for self-correlation + +## Expected Output + +The plot should display a square or rectangular heatmap where each cell represents the Pearson correlation coefficient between two variables. The color intensity should represent the strength of correlation, typically using a diverging color scheme where red/warm colors indicate positive correlation, blue/cool colors indicate negative correlation, and white/neutral indicates no correlation. The actual correlation values should be displayed in each cell for easy reading. The axes should show all variable names clearly, and a color bar should provide reference for the correlation scale. + +## Tags + +heatmap, correlation, statistical, multivariate + +## Use Cases + +- Feature selection in machine learning to identify correlated predictors +- Exploratory data analysis in financial datasets to find asset correlations +- Quality control in manufacturing to identify related process parameters +- Medical research to find relationships between clinical measurements +- Market research to understand customer behavior patterns across variables +- Climate data analysis to identify relationships between weather variables \ No newline at end of file