The Project
I am trying to dynamically turn on/off the display of data for a circos-esque plot that I generated.
The Code
I have data stored in mfData
and a compiled list of data about that in mfIndex
, primarily used for how many data sets there are (number of sectors, etc.).
Here are the steps that I have taken (3 & 4 are wrapped in Dynamic[]
):
Variables - I started the dynamic compilation of the code under the impression that I would need a variable for each sector set to True/False. So I generated n expressions and evaluated each to True to start off.
vars = Table[ToExpression[StringJoin["sector", ToString[n], "=True"]], {n, 1, Length[mfIndex]}]
Outer Rings - The rings are generated and wrapped in
Button[]
which switches the variableoRings = Table[Button[{color, Tooltip[Rotate[ring[outer_radius, inner_radius, angular_size], angle, {0, 0}], "Text"]}, (Symbol[StringJoin["sector", ToString[m]]] = Symbol[StringJoin["sector", ToString[m]]] /. {True -> False, False -> True})], {m, 1, Length[mfIndex]}]
Choice - My hope was that the button directive would turn each variable to True/False when being clicked which would update pick and curves
pick = Pick[Range[Length[mfIndex]],vars]
Curves - The Bezier Curves are generated
curves = Table[Table[BezierCurve[{pt1, pt2, pt3}],{n,1,Length[mfData[[n]]]}],{n,pick}]
The (Apparent) Problem
There are no errors when evaluated, but when I click on one of the rings an error comes up (I tried using both ToExpression[]
and Symbol[]
in the Outer Ring evaluation)
Set::write: Tag ToExpression in ToExpression[sectorm] is Protected. >>
Set::write: Tag Symbol in Symbol[sectorm] is Protected. >>
Meaning that when the Outer Ring code is evaluated the variables aren't being processed into their proper form... "sectorm" instead of {sector1, sector2, etc...}.
I know this is a bit long-winded to get to this question, but is there a better way to evaluate (compose) the variables? Or to accomplish the same thing or re-evaluating the display of data?
(I can provide more explanation if necessary, I tried to reduce this a bit for simplicity's sake...)
(Update) Minimal non-working example
(I think that copied over correctly...)
ring[o_, i_, s_, p_] := Module[{q, oP, iP, cut}, q = (s)/(2 Pi); oP = Table[{o Cos[k q 2 Pi/p], o Sin[k q 2 Pi/p]}, {k, 1, p}]; iP = Table[{i Cos[k q 2 Pi/p], i Sin[k q 2 Pi/p]}, {k, 1, p}]; cut = Polygon[Flatten[{oP, Reverse@iP}, 1]]; Return[cut]];
cir[x_, r_] := {r*Cos[x], r*Sin[x]}
Dynamic[vars = Table[ToExpression[StringJoin["sector", ToString[n]]], {n, 1, 8}]];
Table[ToExpression[StringJoin["sector", ToString[n], "=True"]], {n, 1, 8}];
points1 = Table[{RandomReal[{0 + m*(Pi/4), Pi/4 + m*(Pi/4) - Pi/64}], RandomReal[{0 + (m + 2)*(Pi/4), Pi/4 + (m + 2)*(Pi/4)}]}, {4}, {m, 0, 7}];
points2 = Table[Table[{points1[[n, o, 1]], If[Abs[points1[[n, o, 2]] - points1[[n, o, 1]]] > Pi, (points1[[n, o, 1]] + points1[[n, o, 2]])/2 + Pi, (points1[[n, o, 1]] + points1[[n, o, 2]])/2], points1[[n, o, 2]]}, {o, 1, 8}], {n, 1, 4}];
Dynamic[outRing = Table[Button[Rotate[ring[1.1, 1.05, Pi/4 - Pi/64, 1000], Pi/4*(n - 1), {0, 0}], (ToExpression[StringJoin["sector", ToString[n], "=", ToString[Not[Symbol[StringJoin["sector", ToString[n]]]]]]])], {n, 1, 8}]];
Dynamic[pick = Pick[Range[8], Table[Symbol[StringJoin["sector", ToString[n]]], {n, 1, 8}]]];
Dynamic[inCurve = Table[Table[BezierCurve[{cir[points2[[o, n, 1]], 1], cir[points2[[o, n, 2]], 0.3], cir[points2[[o, n, 3]], 1]}], {n, pick}], {o, 1, 4}]];
Dynamic[Graphics[{outRing, inCurve}]]
ToExpression[ StringJoin["sector", ToString[m], "=", ToString[Not[Symbol[StringJoin["sector", ToString[m]]]]]]]
$\endgroup$Dynamic
followed by;
indicates a failure to understand whatDynamic
does. Before proceeding any further on this please read all the relevant docs and tutorials onDynamic
.Dynamic
only updates pixels on the screen. If you suppress output (i.e. no pixels)Dynamic
is completely redundant. The same section of docs also address the use of e.g.Table[With {i=i},...],...]
and when and why it is necessary. $\endgroup$