plotly marker size relative to data to plot interactive wafer map

Viewed 1147

I would like to create interactive wafer maps with python unsing plotly. The plot shall show the different categorical bins of the single chips e.g. bin 1 all good chips, bin 2 all fails... Now the problem, when i use px.scatter(...) i get all the nice functionality with mouse over and a dynamic legend that i want but the single chips don't align:

dynamic but not aligned.

I tried go.layout.Shape(...) - then i get what I want visually but loose the interactivity:

aligned but now dynamic.

Plotly documentation kind of points out this trade-off between shapes and traces (https://plotly.com/python/shapes/).

Any suggestions? Can i rescale plot markers accordingly when I read out the axis ranges and know the image size? one problem might be, that sometimes chips are not quadratic but just rectangular - can i pass an aspect ratio to the marker?

Maybe plotly aint the right tool for what i want?

2 Answers

I think you can accomplish the desired chart using a heatmap which is basically a specialized scatter plot with categorical axes, and colors for different values.

I don't know the exact format of your data, but I downloaded a dataset of wafer maps from Kaggle, where the first column of the DataFrame contains a 2D array, and each row is a unique wafer. You can then pass any of the 2D arrays directly as an argument to px.imshow and get a heatmap:

df = pd.read_pickle("LSWMD.pkl")
wafer = df.iloc[0,0]

fig = px.imshow(wafer)
fig.show()

enter image description here

I got a little further... I can stack multiple traces of heatmaps now but I still miss the clickable legend - the initial reason to go with plotly. I used abstract data now to simplify.

One could adjust the go.Heatmap object to change its legend but that is beyond my scope. What i tried is to use buttons but they dont work consistently (when used initially they sometimes need 2 clicks) and I cannot change the colour of individual buttons (only off a set of buttons, but it would be close to impossible to align e.g. 20 sets nicely). Any suggestions?

PS: How can I post my html version of the graph?

import pandas as pd
import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots

demo_matrix = np.empty((3,3))
demo_matrix[:] = np.nan
demo_matrix[1,1] = 1
demo_matrix[1,2] = 2
demo_matrix

fig = make_subplots()

fig.add_trace(go.Heatmap(z=np.where(demo_matrix!=1, np.nan, demo_matrix),colorscale = [[0, 'blue'], [1, 'blue']], hoverinfo='skip'))
fig.add_trace(go.Heatmap(z=np.where(demo_matrix!=2, np.nan, demo_matrix),colorscale = [[0, 'red'], [1, 'red']], hoverinfo='skip'))

#trace for hover info - not perfect yet
fig.add_trace(go.Heatmap(z=demo_matrix,colorscale = [[0, 'red'], [1, 'red']],opacity=0))

fig.update_traces(showscale=False)

button_1 = dict(
    method='restyle',
    label="red",
    visible=True,
    args=[{'visible':True}, [1]],
    args2 = [{'visible': False}, [1]],
)

button_2 = dict(
    method='restyle',
    label="blue",
    visible=True,
    args=[{'visible':True}, [0]],
    args2 = [{'visible': False}, [0]],
)

button_3 = dict(
    method='restyle',
    label="all",
    visible=True,
    args=[{'visible':True}],
    args2 = [{'visible': False}],
)

fig.update_layout(width=500, height=500,
    updatemenus=[
        dict(
            type = "buttons",
            direction = "left",
            buttons=[button_1,button_2, button_3],
            pad={"r": 5, "t": 5},
            showactive=False,
            x=.1,
            xanchor="left",
            y=1.1,
            yanchor="top",
            bgcolor = '#AAAAAA',
            bordercolor = '#FFFFFF',
            font=dict(color="red")
        ),
    ]
)
fig.show()
fig.write_html("test.html")
Related