CoolFace
Apppublic

pepperumo/MVTec_Website

sourceHugging Facemitupdated 2y agoView on Hugging Face
3likes
data_processing.py199 linesDownload Raw Back to root
1import pandas as pd
2import plotly.graph_objects as go
3import streamlit as st
4from PIL import Image
5from joypy import joyplot
6import seaborn as sns
7import matplotlib.pyplot as plt
8
9# Function to load dataset
10def load_dataset():
11    file_path = "Data/mvtec_meta_features_dataset.csv"
12    try:
13        complete_df = pd.read_csv(file_path)
14
15        # Show available column names for debugging
16        print("Available columns:", complete_df.columns)
17
18        # Verify column presence
19        required_columns = ["category", "set_type", "anomaly_status"]
20        for col in required_columns:
21            if col not in complete_df.columns:
22                raise KeyError(f"Missing required column: {col}")
23        
24        # Define the subclasses for each category
25        subclasses = {
26            'Texture-Based': ['carpet', 'wood', 'tile', 'leather', 'zipper'],
27            'Industrial Components': ['cable', 'transistor', 'screw', 'grid', 'metal_nut'],
28            'Consumer Products': ['bottle', 'capsule', 'toothbrush'],
29            'Edible': ['hazelnut', 'pill']
30        }
31
32        # Add a new column to the DataFrame to store the subclass
33        complete_df['subclass'] = complete_df['category'].apply(
34            lambda x: next((key for key, value in subclasses.items() if x in value), 'Unknown')
35        )
36
37        # Reorder columns to place 'subclass' after 'category'
38        cols = list(complete_df.columns)
39        cols.insert(cols.index('category') + 1, cols.pop(cols.index('subclass')))
40        complete_df = complete_df[cols]
41
42        return complete_df
43    except Exception as e:
44        st.error(f"Error loading dataset: {e}")
45        return None
46
47# Function to generate dataset statistics
48def dataset_statistics():
49    df = load_dataset()
50    if df is not None:
51        print("Loaded dataset preview:\n", df.head())  # Debugging step
52
53        # Aggregate counts for each category and condition
54        train_normal = df[(df['set_type'] == 'train') & (df['anomaly_status'] == 'normal')].groupby('category').size()
55        test_normal = df[(df['set_type'] == 'test') & (df['anomaly_status'] == 'normal')].groupby('category').size()
56        test_anomalous = df[(df['set_type'] == 'test') & (df['anomaly_status'] == 'anomalous')].groupby('category').size()
57
58        # Combine into a single DataFrame
59        final_summary = pd.DataFrame({
60            'Train Normal Images': train_normal,
61            'Test Normal Images': test_normal,
62            'Test Anomalous Images': test_anomalous
63        }).fillna(0).reset_index()
64
65        return final_summary
66    return None
67
68# Function to generate the bar chart
69def dataset_distribution_chart(df):
70    fig = go.Figure()
71
72    fig.add_trace(go.Bar(
73        x=df['category'], 
74        y=df['Train Normal Images'], 
75        name='Train Normal Images',
76        marker_color='blue'
77    ))
78    fig.add_trace(go.Bar(
79        x=df['category'], 
80        y=df['Test Normal Images'], 
81        name='Test Normal Images',
82        marker_color='red'
83    ))
84    fig.add_trace(go.Bar(
85        x=df['category'], 
86        y=df['Test Anomalous Images'], 
87        name='Test Anomalous Images',
88        marker_color='green'
89    ))
90
91    # Update layout
92    fig.update_layout(
93        title="Distribution of Normal and Anomalous Images per Category",
94        xaxis_title="Categories",
95        yaxis_title="Number of Images",
96        barmode='stack',
97        legend_title="Image Types"
98    )
99
100    # Display chart in Streamlit
101    st.plotly_chart(fig, use_container_width=True)
102
103# Function to display the complete dataframe with expander
104def display_dataframe():
105    df = load_dataset()
106    if df is not None:
107        with st.expander("Show Complete DataFrame"):
108            st.dataframe(df)
109
110
111
112def plot_bgr_pixel_densities(df, pixel_columns=['num_pixels_b', 'num_pixels_g', 'num_pixels_r']):
113    """
114    Generate JoyPy density plots for pixel counts of BGR channels for a given category.
115
116    Parameters:
117        df (pd.DataFrame): Filtered DataFrame for a single category.
118        pixel_columns (list): List of column names for BGR pixel counts.
119
120    Returns:
121        None
122    """
123    if df.empty:
124        st.warning("⚠️ No data available for the selected category.")
125        return
126
127    # Plot JoyPy density plot
128    fig, axes = joyplot(
129        data=df,
130        by="category",  # Group by category
131        column=pixel_columns,
132        color=['blue', 'green', 'red'],  # Colors for BGR channels
133        alpha=0.5,
134        fade=True,
135        legend=True,
136        linewidth=1.0,
137        overlap=3,
138        figsize=(8, 6)  # Adjust the figure size here
139    )
140
141    # Add title and labels
142    plt.title(f'Density Plots for {df["category"].unique()[0]}', fontsize=14)
143    plt.xlabel('Number of Pixels Density', fontsize=12)
144    plt.ylabel('Categories', fontsize=12)
145
146    # Show the plot in Streamlit
147    st.pyplot(fig)
148
149    
150def plot_pair_plots(complete_df):
151    """
152    Generate and display pair plots for each category in the dataset.
153
154    Parameters:
155        complete_df (pd.DataFrame): The input DataFrame containing image features and categories.
156
157    Returns:
158        None
159    """
160
161    # Define the features to be included in the pairplot
162    features = ['num_pixels_b', 'num_pixels_g', 'num_pixels_r', 'perceived_brightness']
163
164    # Create a separate pairplot for each category
165    for category in complete_df['category'].unique():
166        # Filter data for current category
167        category_df = complete_df[complete_df['category'] == category]
168        
169        # Check if the filtered DataFrame is not empty
170        if not category_df.empty:
171            # Create PairGrid with hue and palette
172            g = sns.PairGrid(category_df, vars=features, hue='anomaly_status', palette={'normal': 'blue', 'anomalous': 'red'})
173            
174            # Map the plots to the grid
175            g.map_upper(sns.scatterplot, alpha=0.6)
176            g.map_diag(sns.histplot, kde=True)
177            g.map_lower(sns.scatterplot, alpha=0.6)  
178            
179            # Add legend
180            g.add_legend()
181            
182            # Customize the plot
183            g.figure.suptitle(f'Feature Relationships for {category.title()}', y=1.02, fontsize=14)
184            
185            # Improve label readability
186            for i in range(len(g.axes)):
187                for j in range(len(g.axes)):
188                    if g.axes[i][j] is not None:
189                        g.axes[i][j].set_xlabel(g.axes[i][j].get_xlabel().replace('_', ' ').title())
190                        g.axes[i][j].set_ylabel(g.axes[i][j].get_ylabel().replace('_', ' ').title())
191            
192            # Adjust legend position to the right without overlapping the plots
193            g._legend.set_bbox_to_anchor((1.05, 0.5))
194            g._legend.set_loc('center left')
195            
196            plt.tight_layout()
197            st.pyplot(g.figure)
198
199