# How to plot a signal (function) on a graph (object of graph theory)

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)?

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];
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"]


• @peter Thanks a lot. Sep 17 at 17:47
• @RIGOBERTFOKAM who's peter? Sep 17 at 17:48
• Thanks @flinty. Sep 18 at 11:48
• Sep 18 at 16:07
• Thank a lot @flinty Sep 22 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"]