-1

Purpose

To use variable name as file name conveniently.

Code

Special thanks to @J.M.'s tips!

Remove@"Global`*"
p = Plot[#, {x, 0, 1}] & /@ {x, 1/x};

SetAttributes[g, HoldAll]
g[p_] := Export[ToString@Unevaluated@p <> ".png", p]

(* Few images: *)
{g@p[[1]], g@p[[2]]}

(* Many images: *)
g /@ Hold @@
    Table["p[[" <> ToString@i <> "]]", {i, Length@p}] //
        ToString // ToExpression // ReleaseHold

Question

I'm not satisfied with this two lines in the last section of the above code:

    Table["p[[" <> ToString@i <> "]]", {i, Length@p}] //
        ToString // ToExpression

I believe there are smarter ways to implement that, please teach me, thanks!

ooo
  • 564
  • 3
  • 11
  • I don't know if you realize that your p no longer contains the symbols p1 or p2, which is why you get the results you see when mapping over p. Using Hold[p1, p2] might be more helpful to you. – J. M.'s missing motivation Mar 10 '18 at 10:21
  • That's what ReleaseHold[] is for: ReleaseHold[{g /@ Hold[p1, p2]}]. Again, InputForm[p] will reveal at once that you can't use p to refer to p1 and p2. – J. M.'s missing motivation Mar 10 '18 at 10:30
  • @J.M. So how to directly/conveniently use variable names as filenames? – ooo Mar 10 '18 at 16:16
  • Wasn't my last comment clear? Using your g[]: p = Hold[p1, p2]; ReleaseHold[{g /@ p}] – J. M.'s missing motivation Mar 10 '18 at 21:54
  • Please clean it up a little, make a clear question with a nice use case example and self answer with whatever fits your needs. Otherwise it will be closed as too localized / not clear as in this for it won't help future visitors. – Kuba Mar 12 '18 at 08:02
  • @Kuba Is it okay now? – ooo Mar 12 '18 at 08:15
  • @ooo by self answer I meant to move solution to an answer. And if those questions are not related they should not be inside one topic. – Kuba Mar 16 '18 at 10:42

1 Answers1

1

Maybe something in this line might do:

SetAttributes[ g, HoldFirst ];
g[ sym_ ] := With[
  {
    baseFileName = SymbolName @ Unevaluated @ sym,
    ext = ".png"
  },
  Switch[ sym,
    { __Graphics }, 
      Range@Length@sym // Scan[ Export[ baseFileName <> ToString @# <> ext, sym[[#]] ] & ],
    _Graphics, Export[ baseFileName <> ext, sym ]
  ]
]

With a single plot this will then be immediately exported, while with a list of plots (e.g. Graphics), the symbol's name will be given an additional counter (e.g. p1.png).

SetDirectory @ NotebookDirectory[];
g[p]
(* will write p1.png and p2.png *)
gwr
  • 13,452
  • 2
  • 47
  • 78