# How to use Hold on a variable defined as a graph

I'm working on doing operations on different graphs and getting their probability node degree distributions using a simple algorithm.

If I have many defined graphs, for example:

g=RandomGraph[{5, 6}];
h=RandomGraph[{15, 10}];


What "Hold" operation do I want to use in order to get the output of the graph's name? e.g. "g" or "h"

Here Is my code:

plotting[g_Graph] := Module[{probs1, purged, r = Range@Max@VertexDegree@g},
probs1 = {#, Probability[x == #, x \[Distributed] VertexDegree[g]]} & /@ r;
purged = DeleteCases[probs1, {x_, y_} /; x y == 0];
ListPlot[Log@purged, Frame -> True,
FrameLabel -> {{HoldForm[ln P[K]], g}, {HoldForm[ln K], None}}, PlotLabel -> HoldForm[g]]


My question is specifically: Inside of PlotLabel, when I use

PlotLabel->HoldForm[g]


How can I get that to output either "g" or "h" or whatever the inputted graph is?

I've tried all sorts of Hold functions (HoldFirst etc...), and I suspect that I need to use a String-type expression but I haven't been able to narrow it down.

• You need to SetAttributes[plotting, HoldAll]. The rest looks fine, though I didn't test. Check here, in particular Nonstandard Evaluation. – Szabolcs Dec 1 '14 at 1:35
• @Szabolcs I looked through it and still having trouble. Would I use it inside of module? but don't I want to g to be evaluated in there? – E3labs Dec 1 '14 at 4:41

As indicated by @Szabolcs, you just have to use SetAttributes[plotting, HoldAll] or even in your case SetAttributes[plotting, HoldFirst] (because you have only one argument) when defining your function.
But then, there is a problem to test the header of the function argument, plotting[g_Graph] won't never plot anything because as g is now by defintion maintained in an unevaluated form, its header is Symbol not Graph. However there is a workaround for this using the condition /;test.

See for example this function :

SetAttributes[func, HoldFirst];
func[x_ /; GraphQ[x]] := {Head@x, x, x // OutputForm, HoldForm[x],
Range@Max@VertexDegree@x}


### Tests :

 func[12]
(* as expected returns func[12] because 12 is not a Graph *)


and

g = RandomGraph[{5, 6}];
func[g]


gives

### To record the input command :

As you notice, the form g // OutputForm which gives Graph[< 5 >, < 6 >] is probably more useful than just the name of the variable g.
But you can also "record" the exact command which produced the graph with this small universal function for example :

SetAttributes[rec, HoldFirst]
rec[input_] := {ToString@HoldForm@input, input}


Then

g = rec[RandomGraph[{5, 6}]]


gives

gis now a list containing the command and the result of the command. You'll have of course to modify your other functions, so they can handle this type of list as their new argument.

• I got here trying to understand the differences between testing pattern f[g_Graph] and f[g_?GraphQ]. Above different usage syntax, is this the only difference: that ?GraphQ forces evaluation of the argument to the function that may have HoldFirst set? Are there other cases? – BoLe Nov 2 '15 at 10:20
• If you meant that I could have used x_?GraphQ instead of x_ /; GraphQ[x] you are perfectly right, the result would be the same here. I just missed that ! :) Now, I don't know if I understand well your question but : the fundamental difference is that g_Graph tests the type or Head of the g expression, and g_?GraphQ applies the test GraphQ to g which consists – SquareOne Nov 6 '15 at 11:47
• in testing the head of the (as you say) evaluated form of g. With the PatternTest or ? you can however actually apply any other test to the g expression (not only test the head). Concerning the evaluation of a held expression with ? or using the condition form /;  look at the examples of the last section Possible Issues. – SquareOne Nov 6 '15 at 11:50