Graph3D: reemplaza los vértices con MoleculePlot3D
¿Cómo podemos reemplazar los vértices en un gráfico de 3 dimensiones con Graphics3Dobjetos individuales?
En mi caso concreto quiero visualizar una red química y reemplazar los vértices con sus respectivas MoleculePlot3Drepresentaciones. Como avance, ese es el gráfico 3D actual con el que estoy trabajando. Probablemente puedas imaginar la aplicación final :)
Usé las ideas de esta publicación para configurar las coordenadas.
Las esferas rojas deben reemplazarse con gráficos de moléculas de 3 dim.
Considere este ejemplo mínimo:
Graph3D[{"CO" \[DirectedEdge] "C", "CO" \[DirectedEdge] "O"}]
Configurando las MoleculePlot3Dinstancias correspondientes:
vert = AssociationThread[
{"CO", "C", "O"} -> {
MoleculePlot3D[Molecule[{Atom["[C]"], Atom["[O]"]}, {Bond[{1, 2}, "Double"]}]],
MoleculePlot3D[Molecule[{Atom["[C]"]}]],
MoleculePlot3D[Molecule[{Atom["[O]"]}]]}]
Sin embargo, tengo dificultades para reemplazar los vértices en Graph3Dforma programática. Logré modificar el gráfico 2D:
Graph[{
Annotation["CO", VertexShapeFunction -> (Inset[vert["CO"], #1, Center, 2*#3] &), VertexSize -> 0.2],
Annotation["C", VertexShapeFunction -> (Inset[vert["C"], #1, Center, 2*#3] &), VertexSize -> 0.2],
Annotation["O", VertexShapeFunction -> (Inset[vert["O"], #1, Center, 2*#3] &), VertexSize -> 0.2]},
{"CO" \[DirectedEdge] "C", "CO" \[DirectedEdge] "O"}]
¿Cómo puedo hacer esto en Graph3D? En el caso completo estaré trabajando con las siguientes moléculas:
{"C", "C+", "CH", "CH+", "CN", "CO", "CS", "CS+", "H", "H2", "HCO+",
"HCS+", "He", "N", "O", "OH", "S", "SO", "CH2+", "CO+", "O+", "OCS+",
"S+", "SO+", "CH2", "CN+", "H2O", "HCN", "HS", "H3O+", "HS+", "CH3+",
"HNC", "H3CO+", "CH4", "N+", "N2", "H+", "OH+", "OCS", "H2O+", "H2+",
"H2S+", "H3+", "He+", "O2", "SO2"}
Por lo tanto, moléculas relativamente pequeñas sin la necesidad de escalar mucho en MoleculePlots.
Respuestas
Esta respuesta evita Insetpor completo y toma las primitivas gráficas desde dentro de la expresión de un sistema MoleculePlot3Dy, por lo tanto, es un poco frágil porque podría romperse en una versión futura que reestructura la salida de MoleculePlot3D.
La inspección muestra que Graphics3D devuelto por MoleculePlot3D siempre contiene un GraphicsComplexcon todos los átomos y enlaces. Entonces podemos usar eso GraphicsComplexy envolverlo GeometricTransformationpara hacer que la forma del vértice funcione
molVertex[mol_][coords_, vertex_, scale_] := Module[
{graphic = MoleculePlot3D @ mol, gc},
gc = Cases[graphic, _GraphicsComplex, Infinity];
GeometricTransformation[
gc,
TranslationTransform[coords] @* ScalingTransform[scale]
]
]
Aquí hay un ejemplo,
SeedRandom @ 42;
g = RandomGraph @ {5, 8};
mols = Map[
Molecule,
{"CCCC(C)(C)OCC", "SC1CCCC1", "O=P(O)(O)CCO", "CCCC", "F[Ti](Cl)(Cl)Cl"}
];
Graph3D[
Annotation[#,
VertexShapeFunction -> molVertex[mols[[#]]],
VertexSize -> 0.2
]& /@ VertexList[g],
EdgeList @ g
]