In this step, we are trying to find the shared error contribution of all 13 trials.
4.3.1 The Intution Behind Shared Error :
The idea is to find the a specific card from each sheet, that has minimum color difference
or
minimum del E to the MasterCard among all 42 cards, out of all 13 sheets. So at the end of
this
step, we will have a list of 13 cards that have minimum color difference or minimum del E to
the
MsterCard, we may call these 13 cards as "Best Trial Card" for each sheet out of all 13
sheets.
Next we should understand that those 13 cards will have little variation from the
MasterCard,
but how much do each so called "Best Cards" contribute to the total trial error ?, Let's
try to find out step-by-step.
4.3.2 Identifying the Card with Minimum ΔE :
To find the card with the minimum ΔE in each sheet, we define a function that iterates
through all cards in a sheet that calculates the average ΔE for each card when compared to
the MasterCard, and identifies the card with the lowest average ΔE.
# Find the card with the minimum delta E in each sheet
def find_min_delta_e_card(sheet):
min_delta_e = float('inf')
min_card = None
for card_id, card in sheet.items():
delta_e = np.mean([color_difference(card.iloc[i], master_card.iloc[i]) for i in range(len(card))])
if delta_e < min_delta_e:
min_delta_e = delta_e
min_card = card_id
return min_card, min_delta_e
This function find_min_delta_e_card ensures we identify the card that best matches the
MasterCard from each sheet.
4.3.3 Identifying Best Trial Cards :
We apply the find_min_delta_e_card function across all sheets to identify the "Best Trial
Card" for each sheet and record the minimum ΔE values.
min_delta_e_values = []
for sheet_id, sheet in demo_sheets.items():
min_card, min_delta_e = find_min_delta_e_card(sheet)
min_delta_e_values.append((sheet_id, min_delta_e))
This process yields a list of tuples where each tuple contains a sheet ID and the
corresponding minimum ΔE value.
4.3.4 Ranking Sheets by ΔE:
Next, we rank the sheets based on their minimum ΔE values. We also calculate the total ΔE
and the percentage contribution of each sheet to this total. By sorting and calculating
percentages, we can better understand which sheets have the closest match to the MasterCard
and their relative contributions to the total error.
# Rank the sheets by delta E values
min_delta_e_values.sort(key=lambda x: x[1])
total_delta_e = sum([x[1] for x in min_delta_e_values])
percentages = [(x[0], (x[1] / total_delta_e) * 100) for x in min_delta_e_values]
4.3.5 Visualizing Error Contribution :
To visualize the error contribution of each sheet, we create a ring plot (donut chart)
showing the percentage contribution of each sheet to the total trial error.
import matplotlib.pyplot as plt
# Plotting the ring plot
fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(aspect="equal"))
data = [x[1] for x in percentages]
labels = [f'Sheet {x[0]}\n{round(x[1], 2)}%' for x in percentages]
wedges, texts = ax.pie(data, wedgeprops=dict(width=0.3), startangle=-40)
# Annotate with sheet numbers and percentages
for i, p in enumerate(wedges):
ang = (p.theta2 - p.theta1) / 2. + p.theta1
y = np.sin(np.deg2rad(ang))
x = np.cos(np.deg2rad(ang))
horizontalalignment = {-1: "right", 1: "left"}[int(np.sign(x))]
# Add straight line connection
ax.annotate(labels[i], xy=(x, y), xytext=(1.35 * x, 1.4 * y),
horizontalalignment=horizontalalignment,
bbox=dict(boxstyle="round,pad=0.5", fc="w"),
arrowprops=dict(arrowstyle="-", connectionstyle="arc3,rad=0.0"))
plt.suptitle("Error Contribution of All 13 Sheets", fontsize=20, y=1.02)
plt.show()
4.3.6 Donut Chart Visualisation for Shared Error Contributio :
4.4 Acurracy of Trials across all the sheets
IN this step, we are trying to visualise how is the color difference between Mastercard
and the 'Best Card' with "minimum del E" amongst each sheet across all 13 sheets.
If the plots are scrutinised closely then it can be easily intrepreted that for each
sheet there is a strong difference in color between (6,2) squares of MasterCard and the
"Best card" with minimum del E in that specific sheet amongst 42 cards.
4.4.1 Heatmap Visualisation : Accuracy of trials across all Sheets
The script visualizes these findings by plotting 13 heatmaps, illustrating the
accuracy
of trials across all sheets, with each heatmap representing a different sheet's
data.
These visualizations help in understanding how closely each trial card matches the
master card, aiding in evaluating experimental outcomes efficiently.
The Code Snippet
# Plotting the 13 heatmaps
fig, axs = plt.subplots(4, 4, figsize=(15, 15))
axs = axs.flatten()
for idx, card in enumerate(min_delta_e_cards):
delta_e_matrix = calculate_delta_e_matrix(card, master_card)
sns.heatmap(delta_e_matrix, cmap='Blues_r', cbar=False, ax=axs[idx])
axs[idx].invert_yaxis() # Invert the y-axis
axs[idx].set_title(f'Sheet {idx + 1}')
axs[idx].axis('off')
# Remove extra subplots
for idx in range(len(min_delta_e_cards), len(axs)):
fig.delaxes(axs[idx])
# Add a colorbar
fig.subplots_adjust(bottom=0.1)
cbar_ax = fig.add_axes([0.25, 0.05, 0.5, 0.02])
fig.colorbar(axs[0].collections[0], cax=cbar_ax, orientation='horizontal', label='Delta E')
plt.suptitle('Heatmap : Accuracy of trials across all Sheets', y=0.95, fontsize=25)
plt.show()
4.4.2 Circular Color Difference with MasterCard : Accuracy of trials across Sheets
We visualize the color differences by plotting 13 subplots (arranged in a 3x5 grid)
using Matplotlib. Each subplot represents a sheet from our dataset, where we
identify and highlight the color card with the minimal delta E (color difference)
compared to a predefined master card. Circles within each subplot depict the Lab
color values of the ideal card (found to have minimal delta E) and the master card.
The color of each square indicates the magnitude of color difference between the
ideal card and the master card, ranging from black (no difference) to white (maximum
difference). This visual approach helps in understanding how closely each
experimental trial matches the master card, aiding in evaluating trial accuracy
across all sheets effectively.
The Code Snippet
# Iterate through each sheet to plot minimum delta E cards
plot_counter = 0
for sheet_id, sheet in demo_sheets.items():
if plot_counter >= 13: # Adjust to the number of sheets you want to visualize
break
min_delta_e = float('inf')
min_card = None
# Find the card with minimum delta E in the current sheet
for card_id, card in sheet.items():
delta_e = np.mean([color_difference(card.iloc[i], master_card_df.iloc[i]) for i in range(len(card))])
if delta_e < min_delta_e:
min_delta_e = delta_e
min_card = card_id
# Plotting the minimum delta E card for the current sheet
ideal_card = sheet[min_card]
# Set axis limits
axes[plot_counter].set_xlim(0, 8)
axes[plot_counter].set_ylim(0, 8)
# Invert y-axis to correct orientation
#axes[plot_counter].invert_yaxis()
for i in range(8):
for j in range(8):
color_diff = color_difference(ideal_card.iloc[i*8 + j], master_card_df.iloc[i*8 + j])
intensity = color_diff / 100.0 # Normalize to range [0, 1]
color = plt.cm.gray(1 - intensity) # Black to white
# Plotting the colored square
rect = patches.Rectangle((j, i), 1, 1, color=color, alpha=1.0)
axes[plot_counter].add_patch(rect)
# Plotting the circles for ideal_card and master_card
ideal_color = lab_to_rgb(ideal_card.iloc[i*8 + j]['L'], ideal_card.iloc[i*8 + j]['a'], ideal_card.iloc[i*8 + j]['b'])
master_color = lab_to_rgb(master_card_df.iloc[i*8 + j]['L'], master_card_df.iloc[i*8 + j]['a'], master_card_df.iloc[i*8 + j]['b'])
ideal_circle = patches.Circle((j + 0.35, i + 0.5), 0.3, edgecolor='none', facecolor=ideal_color)
master_circle = patches.Circle((j + 0.65, i + 0.5), 0.3, edgecolor='none', facecolor=master_color)
axes[plot_counter].add_patch(ideal_circle)
axes[plot_counter].add_patch(master_circle)
# Set title for each subplot
axes[plot_counter].set_title(f'Sheet {sheet_id}')
axes[plot_counter].set_xticks([])
axes[plot_counter].set_yticks([])
plot_counter += 1
# Create a colorbar below the plot
norm = Normalize(vmin=0, vmax=100) # Adjust according to your maximum color difference
sm = ScalarMappable(cmap='Greys', norm=norm)
# Adjust layout to include colorbar below the plot
fig.tight_layout(rect=[0, 0, 1, 0.95]) # Adjust the bottom margin as needed
# Show the plot
plt.suptitle("Circular Color Difference : Accuracy of trials across Sheets", fontsize=20, y=1.02)
plt.show()