Morning
I am trying to create a 3d scatter plot with the opacity of each point drawn from a column in my dataframe.
I have a dataframe with columns for x,y,z, sample_id, patient_id, diagnosis and sample_purity.
I can create a plot in plotly express like this:
fig = px.scatter_3d(df, x="x", y="y", z="z",
color=df["diagnosis"],
labels={'color': 'Diagnosis'},
hover_data=df[["sample_id", "patient_id", "diagnosis"]],
width = 1600,
height = 800,
title = plotTitle,
hover_name="patient_id"
)
but then when I iterate over the traces in the figure like this:
for trace in fig.data:
marker = trace.marker
hover_name = trace.hovertext
print(hover_name)
the traces each contain multiple samples, and I’d like to change the opacity on a per sample basis. Doing it this way, I could set an opacity for the markers of each diagnosis, but I don’t think I could do it for each sample.
The other way that I tried was to construct the figure from graph objects like this:
fig = go.Figure()
categories = df['diagnosis'].unique()
colors = px.colors.qualitative.Plotly[:len(categories)]
color_mapping = dict(zip(categories, colors))
df['color'] = df['diagnosis'].map(color_mapping)
print(df.shape)
for index, row in df.iterrows():
#print(row[["sample_id", "patient_id", "diagnosis", "cancer_type", "purity"]])
sampleId, patientId, diagnosis, cancerType = row[["sample_id", "patient_id", "diagnosis", "cancer_type"]]
fig.add_trace(go.Scatter3d(mode='markers',
x=[row["x"]],
y=[row["y"]],
z=[row["z"]],
marker=dict(
color=row["color"],
size=4,
opacity = row["purity"
),
name=row["diagnosis"]
)
)
And this sort of works. It gives me variable transparency on a per sample basis, but it also results in multiple traces, one for each sample, which means they are then not color coded or grouped in the plot and legend, Which is less than ideal.
The way that I initially tried, which makes the most sense to me, would have been to pass a column from the dataframe to the opacity variable when I first made the plot, but opacity accepts only a single value. Which I can see being a useful things for some scenarios I guess, but not this one.
Any ideas on how I would go about doing this, would be much appreciated.
Thanks
Ben.