IGraph/M has functions precisely for this. They are implemented purely on Mathematica (they don't use the igraph C core), so you can look at the implementation.
Sadly, making this work reliable and with reasonable performance is not at all easy. It requires distinguishing between the various kinds of properties and crossing the minefield of property-related bugs. So I won't go into details, instead, I'll show how to use the functionality in IGraph/M. For many more example, see its documentation (evaluate IGDocumentation[]
).
Needs["IGraphM`"]
g = ExampleData[{"NetworkGraph", "Friendship"}]

Look at the labels with the vertex property extractor:
IGVertexProp[VertexLabels][g]
(* {Placed["Anna", After], Placed["Rose", Above],
Placed["Nora", Above], Placed["Ben", Before], Placed["Larry", Above],
Placed["Carol", Below], Placed["Rudy", Below],
Placed["Linda", Above], Placed["James", Below]} *)
Make them uppercase by mapping a function over the VertexLabels
property
IGVertexMap[MapAt[ToUpperCase, {1}], VertexLabels, g]
We needed MapAt
, because, as you can see above, all vertex labels are given as Placed
expressions.

Compute edge betweenness values for each edge and store them in the EdgeWeight
property:
wg = g // IGEdgeMap[# &, EdgeWeight -> EdgeBetweennessCentrality]
We are mapping the identity function #&
here, as we don't want to transform the values in any way.
Notice that we used the operator form of IGEdgeMap
.
Copy the value of the EdgeWeight
property to the "betweenness"
edge property:
wg = IGEdgeMap[# &, "betweenness" -> IGEdgeProp[EdgeWeight], wg]
The right-hand-side of ->
must always contain a function that returns a value for each edge in order when applied to the graph. The result will be transformed with the function given as the first argument, and then stored in the property specified in the left-hand-side of ->
.
The IGEdgeProp
and IGVertexProp
property extractors are useful for constructing the RHS of ->
, and are often used alone there. But they can also be combined with other functions. Here's how to colour each edge based on the "betweenness"
edge property. We Rescale
the value to fit the domain of the colour function.
IGEdgeMap[ColorData["Rainbow"],
EdgeStyle -> Rescale@*IGEdgeProp["betweenness"], wg]

Here's a more complex styling example from the documentation, showing operator forms, and mapping a function that takes multiple arguments.
g = Graph[ExampleData[{"NetworkGraph", "EastAfricaEmbassyAttacks"}],
ImageSize -> Medium];
g //
IGEdgeMap[ (* save original weight in "weight" property *)
Identity, "weight" -> IGEdgeProp[EdgeWeight]
] /*
IGEdgeMap[ (* invert edge weights for betweenness calculation; for this purpose we need large weight = weak connection *)
1/# &, EdgeWeight
] /*
IGEdgeMap[ (* thickness by original weight, colour by betweenness based on inverse weight; map two-argument function *)
Directive[AbsoluteThickness[9 #1], ColorData["Rainbow"][#2]] &,
EdgeStyle -> {IGEdgeProp["weight"], Rescale@*EdgeBetweennessCentrality}
]

Finally, here are the usage messages of the functions related to this functionality area:

There's also the question of what to do when a requested property value does not exist. For custom properties, values may be assigned only to some edges/vertices. The current behaviour of IGraph/M is to return Missing[...]
in these cases.