AI/ML
Confusion Matrix Card - ML Model Performance
Visualize ML model classification performance with confusion matrices. Analyze true positives, false positives, and model accuracy metrics interactively.
Confusion Matrix Card
The Confusion Matrix Card displays a confusion matrix visualization showing true positives, false positives, true negatives, and false negatives for classification model evaluation.
Preview
Installation
npx shadcn@latest add https://vectormotion.vercel.app/registry/confusion-matrix-card.jsonConfusion Matrix Card
'use client'import React from 'react';import { Grid } from 'lucide-react';import { motion } from 'motion/react';import { clsx, type ClassValue } from "clsx"import { twMerge } from "tailwind-merge"import { ResponsiveContainer, ScatterChart, Scatter, XAxis, YAxis, Tooltip, Cell, ZAxis } from 'recharts';function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs))}interface MatrixData { x: number; y: number; value: number; label: string; fill: string; [key: string]: any;}interface ConfusionMatrixCardProps { className?: string; title?: string; subtitle?: string; data?: MatrixData[];}const DEFAULT_DATA: MatrixData[] = [ { x: 1, y: 1, value: 850, label: 'TP', fill: '#10b981' }, // True Positive (Emerald) { x: 2, y: 1, value: 42, label: 'FP', fill: '#f43f5e' }, // False Positive (Rose) { x: 1, y: 2, value: 15, label: 'FN', fill: '#f43f5e' }, // False Negative (Rose) { x: 2, y: 2, value: 910, label: 'TN', fill: '#10b981' }, // True Negative (Emerald)];const DEFAULT_TITLE = "Confusion Matrix";const DEFAULT_SUBTITLE = "Predicted vs Actual";export const ConfusionMatrixCard: React.FC<ConfusionMatrixCardProps> = ({ className = "", title = DEFAULT_TITLE, subtitle = DEFAULT_SUBTITLE, data = DEFAULT_DATA,}) => { return ( <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5, delay: 0.1 }} className={cn( "relative overflow-hidden rounded-2xl border border-border bg-card text-card-foreground shadow-sm transition-all hover:border-blue-300 dark:hover:border-blue-700 hover:shadow-md flex flex-col h-full", className )} > <div className="p-5 flex flex-col h-full relative z-10"> <div className="mb-4 flex items-start justify-between"> <div> <h3 className="font-bold text-lg text-foreground"> {title} </h3> <p className="text-sm text-muted-foreground font-medium"> {subtitle} </p> </div> <div className="rounded-lg border-2 border-blue-100 dark:border-blue-800 p-2 text-blue-500 dark:text-blue-400 flex items-center justify-center"> <Grid className="h-5 w-5" /> </div> </div> <div className="flex-1 w-full min-h-[160px] relative"> <ResponsiveContainer width="100%" height="100%"> <ScatterChart margin={{ top: 20, right: 20, bottom: 20, left: 20 }}> <XAxis type="number" dataKey="x" name="Predicted" hide domain={[0, 3]} /> <YAxis type="number" dataKey="y" name="Actual" hide domain={[0, 3]} reversed /> <ZAxis type="number" dataKey="value" range={[4000, 4000]} /> <Tooltip cursor={{ strokeDasharray: '3 3' }} content={({ active, payload }) => { if (active && payload && payload.length) { return ( <div className="rounded-lg border border-zinc-200 dark:border-zinc-700 bg-white dark:bg-zinc-800 p-2 shadow-sm text-xs"> <span className="font-bold">{payload[0].payload.label}:</span> {payload[0].payload.value} </div> ); } return null; }} /> <Scatter data={data} shape={(props: any) => { const { cx, cy, payload } = props; return ( <g> <rect x={cx - 60} y={cy - 40} width={120} height={80} rx={8} fill={payload.fill} opacity={0.2} /> <text x={cx} y={cy - 10} textAnchor="middle" dominantBaseline="middle" className="text-xs font-bold fill-zinc-700 dark:fill-zinc-300"> {payload.label} </text> <text x={cx} y={cy + 15} textAnchor="middle" dominantBaseline="middle" className="text-lg font-bold fill-zinc-900 dark:fill-zinc-50"> {payload.value} </text> </g> ); }}> </Scatter> </ScatterChart> </ResponsiveContainer> </div> <div className="absolute -bottom-4 -right-4 z-0 opacity-5 pointer-events-none"> <Grid className="w-40 h-40 text-blue-500" /> </div> </div> </motion.div> );};Props
Prop
Type
Usage
This component is a demo card displaying confusion matrix data with animated visualizations and dark mode support.