Given a graph of n vertices, it is possible to plot a discrete signal (or function) of n samples on the vertices of the graph, so that one can visualize the features of the signal on the graph (see the attached image)?
2 Answers
g = PetersenGraph[];
(* get the 3d coordinates of the graph vertices *)
coords = Append[#, 0] & /@ GraphEmbedding[g];
points = Point[coords];
(* create lines between the edges *)
connections = EdgeList[g];
lines = Line[coords[[#]]] & /@ (connections /. UndirectedEdge -> List);
(* generate some signals on each vertex as lines pointing upwards *)
SeedRandom[1];
signals = RandomReal[1, VertexCount@g];
signalsLines = MapThread[
Line[{#1, Append[Most@#1, #2]}] &,
{coords, signals}];
(* draw it all in ortho projection *)
Graphics3D[{
{Red, Dashed, lines},
{Red, PointSize[Large], points},
{Blue, signalsLines}
}, Boxed -> False, ViewProjection -> "Orthographic"]
-
$\begingroup$ @peter Thanks a lot. $\endgroup$RIGOBERT FOKAM– RIGOBERT FOKAM2021-09-17 17:47:21 +00:00Commented Sep 17, 2021 at 17:47
-
$\begingroup$ @RIGOBERTFOKAM who's peter? $\endgroup$flinty– flinty2021-09-17 17:48:14 +00:00Commented Sep 17, 2021 at 17:48
-
$\begingroup$ Thanks @flinty. $\endgroup$RIGOBERT FOKAM– RIGOBERT FOKAM2021-09-18 11:48:51 +00:00Commented Sep 18, 2021 at 11:48
-
$\begingroup$ @flinty Good question, but there are others one might ask... $\endgroup$Daniel Lichtblau– Daniel Lichtblau2021-09-18 16:07:00 +00:00Commented Sep 18, 2021 at 16:07
-
$\begingroup$ Thank a lot @flinty $\endgroup$RIGOBERT FOKAM– RIGOBERT FOKAM2021-09-22 11:55:46 +00:00Commented Sep 22, 2021 at 11:55
SeedRandom[1]
signals = RandomReal[1, 10];
To get a 3D graph that looks like the one in OP, we can use signals to specify a custom VertexShapeFunction and use it with PetersenGraph:
PetersenGraph[
EdgeStyle -> Directive[Dashed, Red],
VertexCoordinates -> Append[0] /@ GraphEmbedding[PetersenGraph[]],
EdgeShapeFunction -> "Line",
VertexShapeFunction -> ({Thick, Blue,
Line[{#, # + {0, 0, signals[[#2]]}}], Red, Sphere[#, .03]} &),
ImageSize -> 500
]
More generally, we can use signals as the setting for the options VertexSize and/or VertexStyle
g0 = PetersenGraph[ImageSize -> 300];
g1 = PetersenGraph[ImageSize -> 300,
VertexSize -> {v_ :> signals[[v]]},
VertexStyle -> {v_ :> ColorData["Rainbow"]@Rescale[signals][[v]]},
EdgeStyle -> Directive[Dashed, Red],
EdgeShapeFunction -> "Line",
BaseStyle -> FaceForm[Opacity[.5]]];
Row[{g0, g1}]
To get a 3D graph object simply wrap g1 with Graph3D. Use a custom VertexShapeFunction if you need to depict vertices as lines:
Row[{Graph3D @ g1,
Graph3D[g1,
VertexShapeFunction -> ({Thick, Line @ {#, # + {0, 0, signals[[#2]]}}} &)]}]
We can also use a more flexible custom VertexShapeFunction which allows any 3D graphics primitive as vertex shape:
ClearAll[vShapeF, tF]
tF[x_] := Translate[
Scale[x, If[FreeQ[_Sphere]@x, {.1, .1, #3[[3]]}, #3], {0, 0, 0}], #] &;
vShapeF[prim_: Automatic, d___] :=
Module[{pnt = {AbsolutePointSize[5], Black, Opacity[1], Point[{0, 0, 0}]},
dir = Sequence[Opacity[.5], AbsoluteThickness[2], CapForm[None], d]},
Switch[prim,
Automatic | "Automatic" | Sphere | "Sphere",
tF[{dir, Sphere[], pnt}],
Line | "Line", tF[{dir, Line[{{0, 0, 0}, {0, 0, 1}}], pnt}],
Tube | "Tube", tF[{dir, Tube[{{0, 0, 0}, {0, 0, 1}}, 1], pnt}],
Cylinder | "Cylinder",
tF[{dir, Cylinder[{{0, 0, 0}, {0, 0, 1}}, 1], pnt}],
Cuboid | "Cuboid", tF[{dir, Cuboid[{-1, -1, 0}, {1, 1, 1}], pnt}],
_, tF[{dir, prim, pnt}]]]
Examples:
triangleWaveCube = ChartElementData["TriangleWaveCube",
"AngularFrequency" -> 5, "RadialAmplitude" -> 0.4][{{-1, 1}, {-1, 1}, {0, 1}}];
Multicolumn[
Graph3D[g1, VertexShapeFunction -> vShapeF[ToExpression @ #],
BoxRatios -> If[# == "Automatic", Automatic, {1, 1, 1/2}],
PlotLabel -> Style[#, 16, Black],
ImageSize -> 400] & /@
{"Automatic", "Line", "Tube", "Cylinder", "Cuboid", "triangleWaveCube"},
2, Appearance -> "Horizontal"]





