8
$\begingroup$

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

graph with signal

$\endgroup$
10
$\begingroup$
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"]

enter image description here

$\endgroup$
5
6
$\begingroup$
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
 ]

enter image description here

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}]

enter image description here

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]]}}} &)]}]

enter image description here

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

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.