Here is a BBC dynamic graphics. I am thinking it might be possible to reproduce the graphics in Mathematica.
In the process of answering we will see some charming graphics tricks available in MMA. That is the only reason to ask the question out here.
Update:
I just checked that BBC is using simple JavaScript to do it. They have manually made the static pictures and not even using Flash based event handling. So all the pictures are static entities and once we click on one country it generates a unique image. For other countries it shows other images. The separate images for each cases can be generated via PowerPoint, Visio or even Photoshop. One can check this just by disabling the JavaScript in your browser and by reloading the page.
I understand that those single pictures can be made from MMA. Some answers shows the right direction how one can do it. So I am accepting the best answer that has come so far.
Some more basic footwork for this:
g[\[Alpha]_, \[Beta]_, color_] := Module[{t},
t = Graphics[{{Thickness[.03], Arrowheads[{.15}], color,
Arrow[
BezierCurve[{{Cos[\[Alpha]], Sin[\[Alpha]]}, {0,
0}, {Cos[\[Beta]], Sin[\[Beta]]}}]]}},
PlotRange -> 1.5, ImageSize -> 512, Background -> None];
ImageCompose[Blur[t, 15], t]
]
one = Fold[ImageCompose,
g[0, \[Pi]/3, Blue], {g[0, \[Pi]/2, Blue], g[0, \[Pi], Blue],
g[0, 4 \[Pi]/3, Blue]}]
two = Fold[ImageCompose,
g[\[Pi]/3, 0, Yellow], {g[\[Pi]/3, \[Pi]/2, Yellow],
g[\[Pi]/3, \[Pi], Yellow], g[\[Pi]/3, 4 \[Pi]/3, Yellow]}]
DynamicModule[{pick = 1},
ClickPane[
Dynamic#If[pick == 1, one, two],
Function[{point}, If[First[point] < 256, pick = 1, pick = 2]]]
]
Just another starter:
a = Point[{0, 0}];
b = .75 Tuples[{1, -1}, 2][[{3, 1, 2, 4}]];
PieChart[
{
Button[1, (a = {Thickness[.05], Arrowheads[.1],
Arrow[BSplineCurve#{b[[1]], {0, 0}, #}] & /# b})],
Button[1, (a = {Thickness[.05], Arrowheads[.1],
Arrow[BSplineCurve#{b[[2]], {0, 0}, #}] & /# b})],
Button[1, (a = {Thickness[.05], Arrowheads[.1],
Arrow[BSplineCurve#{b[[3]], {0, 0}, #}] & /# b})],
Button[1, (a = {Thickness[.05], Arrowheads[.1],
Arrow[BSplineCurve#{b[[4]], {0, 0}, #}] & /# b})],
}
,
SectorOrigin -> {Automatic, 1},
Epilog -> Dynamic#a]
Edit More compact:
a = Point[{0, 0}];
b = .75 Tuples[{1, -1}, 2][[{3, 1, 2, 4}]];
PieChart[
ReleaseHold[Replace[Table[
List[1,
ReplaceAll[
Hold[a = {Thickness[.05], Arrowheads[.1],
Arrow[BSplineCurve#{k, {0, 0}, #}] & /# b}], k -> i]],
{i, b}], List -> Button, {2}, Heads -> True]]
,
SectorOrigin -> {Automatic, 1},
Epilog -> Dynamic#a]
This is not a full answer, but it's too long for a comment. I encourage everyone to "steal" from it, and complete it :-)
g = RandomGraph[{5, 12}, DirectedEdges -> True];
SetterBar[Dynamic[v], VertexList[g]]
Dynamic#HighlightGraph[
g, {Style[Cases[EdgeList[g], v \[DirectedEdge] _],
Directive[Thick, Black]], Style[v, Red]},
GraphLayout -> "CircularEmbedding", EdgeStyle -> Lighter#Gray,
VertexLabels -> "Name"]
The next step is using VertexShapeFunction with objects wrapped in EventHandler to replace the SetterBar.
Related
I want to exclude a possible next case under specific conditions.
For example, I have:
token : array 1..2 of {0, 1, 2, 3, 4, 5, 6};
next(token[1]) := case
x : {1, 2, 3, 4, 5, 6};
TRUE : 0;
esac;
next(token[2]) := case
x : {1, 2, 3, 4, 5, 6};
TRUE : 0;
esac;
-- exclude state value 1 if !position1free
...
DEFINE position1free := token[1] != 1 & token[2] != 1;
...
The same for all the values 1..6.
Otherwise, I have to do a lot of combinations to return only the position that are free.
Has anyone an idea if this is possible?
A possible approach is to further constraint the space of states with
TRANS (!position1free) -> (next(token) != 1) ;
Please beware that an inadvertent use of TRANS can result in a Finite State Machine which has no initial state or it contains some state s_i which does not have any future state:
source: nuXmv: Introduction.
I have this simple spark program. I am wondering why all data end up in one partition.
val l = List((30002,30000), (50006,50000), (80006,80000),
(4,0), (60012,60000), (70006,70000),
(40006,40000), (30012,30000), (30000,30000),
(60018,60000), (30020,30000), (20010,20000),
(20014,20000), (90008,90000), (14,0), (90012,90000),
(50010,50000), (100008,100000), (80012,80000),
(20000,20000), (30010,30000), (20012,20000),
(90016,90000), (18,0), (12,0), (70016,70000),
(20,0), (80020,80000), (100016,100000), (70014,70000),
(60002,60000), (40000,40000), (60006,60000),
(80000,80000), (50008,50000), (60008,60000),
(10002,10000), (30014,30000), (70002,70000),
(40010,40000), (100010,100000), (40002,40000),
(20004,20000),
(10018,10000), (50018,50000), (70004,70000),
(90004,90000), (100004,100000), (20016,20000))
val l_rdd = sc.parallelize(l, 2)
// print each item and index of the partition it belongs to
l_rdd.mapPartitionsWithIndex((index, iter) => {
iter.toList.map(x => (index, x)).iterator
}).collect.foreach(println)
// reduce on the second element of the list.
// alternatively you can use aggregateByKey
val l_reduced = l_rdd.map(x => {
(x._2, List(x._1))
}).reduceByKey((a, b) => {b ::: a})
// print the reduced results along with its partition index
l_reduced.mapPartitionsWithIndex((index, iter) => {
iter.toList.map(x => (index, x._1, x._2.size)).iterator
}).collect.foreach(println)
When you run this, you will see that data (l_rdd) is distributed into two partitions. Once I reduced, the resultant RDD (l_reduced) also has two partitions but all the data is in one partition (index 0) and the other one is empty. This happens even if the data is huge (a few GBs). Shouldn't the l_reduced be also distributed into two partitions.
val l_reduced = l_rdd.map(x => {
(x._2, List(x._1))
}).reduceByKey((a, b) => {b ::: a})
With reference to the above snippet, you are partitioning by the second field of the RDD. All the numbers in the second field end with 0.
When you call HashPartitioner, the partition number for a record is decided by the following function:
def getPartition(key: Any): Int = key match {
case null => 0
case _ => Utils.nonNegativeMod(key.hashCode, numPartitions)
}
And the Utils.nonNegativeMod is defined as follows:
def nonNegativeMod(x: Int, mod: Int): Int = {
val rawMod = x % mod
rawMod + (if (rawMod < 0) mod else 0)
}
Let us see what happens when we apply the above two pieces of logic to your input:
scala> l.map(_._2.hashCode % 2) // numPartitions = 2
res10: List[Int] = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
Therefore, all of your records end up in partition 0.
You can solve this problem by a repartition:
val l_reduced = l_rdd.map(x => {
(x._2, List(x._1))
}).reduceByKey((a, b) => {b ::: a}).repartition(2)
which gives:
(0,100000,4)
(0,10000,2)
(0,0,5)
(0,20000,6)
(0,60000,5)
(0,80000,4)
(1,50000,4)
(1,30000,6)
(1,90000,4)
(1,70000,5)
(1,40000,4)
Alternatively, you can create a custom partitioner.
Unless you specify otherwise, the partitioning will be done based on the hashcode of the keys concerned, with the assumption that the hashcodes will result in a relatively even distribution. In this case, your hashcodes are all even, and therefore will all go into partition 0.
If this is truly representative of your data set, there is an overload for reduceByKey which takes the partitioner as well as the reduce function. I would suggest providing an alternative partitioning algorithm for a dataset like this.
Consider the following list :
dalist = {{47.9913, 11.127, 208}, {47.5212, 10.3002, 208},
{49.7695, 9.96838, 160}, {48.625, 12.7042, 436}}
Those are coordinatees of Eye fixations on a screen where, within each sublist,
#1 is the X coordinate,
#2 the Y coordinate and
#3, the duration spent at that particular location
I then use the following :
Disk[{#[[1]], #[[2]]}, 3N[#[[3]]/Total[dalist[[All, 3]]]]] & /# dalist
to draw disk with duration weighted diameter.
I would like to draw cross instead where the 2 segments intersect at their middle and the length of each is equivalent to the disk diameter as illustrated bellow.
This is what I have yet :
Graphics[{
Line[{{#[[1]] - 3 N[#[[3]]/Total[dalist[[All, 3]]]], #[[2]]},
{#[[1]] + 3 N[#[[3]]/Total[dalist[[All, 3]]]], #[[2]]}}] & /# dalist,
Line[{{#[[1]], #[[2]] - 3 N[#[[3]]/Total[dalist[[All, 3]]]]},
{#[[1]], #[[2]] + 3 N[#[[3]]/Total[dalist[[All, 3]]]]}}] & /# dalist}]
I was wondering if there was a simpler way, using something similar to PlotMarkers that exist in ListPlot
Use two lines. Something like:
pointTrans =
{
Line[{{#[[1]] - l, #[[2]]}, {#[[1]] + l, #[[2]]}}],
Line[{{#[[1]], #[[2]] - l}, {#[[1]], #[[2]] + l}}]
} /. l -> #[[3]]/Mean[dalist[[All, 3]]] &;
pointTrans /# dalist // Graphics // Show
As you can already draw the circles, why not just use that like so:
circles=Graphics[Disk[{#[[1]], #[[2]]}, 3 N[#[[3]]/Total[dalist[[All, 3]]]]] & /# dalist]
and then
circles /. Disk[{x_, y_}, r_] :> Line[{{{x, y - r/2}, {x, y + r/2}}, {{x - r/2, y}, {x + r/2, y}}}]
giving
I think a little helper function is convenient here:
makeCross[{x_, y_, r_}, total_] := With[{scale = 3*r/total},
Line[{{{x - scale, y}, {x + scale, y}}, {{x, y - scale}, {x, y + scale}}}]]
total = Total[dalist[[All, 3]]];
Graphics[makeCross[#, mean] & /# dalist]
You could also use BubbleChart:
plus[{x:{x0_, x1_}, y:{y0_, y1_}}, __] :=
Line[{{{x0, Mean[y]}, {x1, Mean[y]}}, {{Mean[x], y0}, {Mean[x], y1}}}]
BubbleChart[dalist, ChartElementFunction -> plus] (*or maybe "MarkerBubble" instead of plus*)
I would like to offer this modification of Artefacto's code.
pointTrans =
With[{l = #3/2/Mean#dalist[[All, 3]]},
Line#{{{# - l, #2}, {# + l, #2}}, {{#, #2 - l}, {#, #2 + l}}}
] &;
Graphics[{Thick, pointTrans ### dalist}]
I've created this theme after my previous post. I can't run the following code (written by #belisarius):
a = Image["path/file.png"]
b = Image#ArrayPad[ImageData#a, {{40, 0}, {40}, {0}}, {1, 1, 1}];
f[image_, angleMult_] := ImageForwardTransformation[image, (
fi = ArcTan[Abs[#[[2]]/(#[[1]] - .5)]];
fi1 = angleMult fi (#[[1]]^2 + #[[2]]^2)/2;
{(1/2 - Sin[fi1] #[[2]] - Cos[fi1]/2 +
Cos[fi1] #[[1]]), -Sin[fi1]/2 + Sin[fi1] #[[1]] +
Cos[fi1] #[[2]]}) &]
t = Table[f[b, x], {x, 0, .2, .02}];
t1 = Reverse#t;
Export["anim.gif", Join[t, t1], "DisplayDurations" -> .15];
Import["anim.gif", "Animation"]
Here is a list of errors:
ArrayPad::depth: Padding amount {{40,0},{40},{0}} should specify padding in no more than the number of dimensions in array {{1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.996078,0.984314,<<142>>},<<49>>,<<145>>}. >>
Image::imgarray: The specified argument ArrayPad[{{1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.996078,0.984314,<<142>>},<<49>>,<<145>>},{{40,0},{40},{0}},{1,1,1}] should be an array of rank 2 or 3 with machine-sized numbers. >>
ImageForwardTransformation::imginv: Expecting an image or graphics instead of Image[ArrayPad[{{1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.996078,0.984314,<<142>>},<<49>>,<<145>>},{<<1>>},{1,1,1}]]. >>
General::stop: Further output of ImageForwardTransformation::imginv will be suppressed during this calculation. >>
Rasterize::bigraster: Not enough memory available to rasterize ImageForwardTransformation expression. >>
General::stop: Further output of Rasterize::bigraster will be suppressed during this calculation. >>
I'm using Mathematica 8 under Linux.
I think I got it.
The code above is for color images (3 channels) and it seems you are trying to run it over a B&W image (1 channel).
Either use a color image or replace the second line by:
b = Image#ArrayPad[ImageData#a, {{40, 0}, {40}}, 1];
Here is the result for your image using the above replacement as:
a = Binarize[Image["path/file.png"]]
b = Image#ArrayPad[ImageData#a, {{40, 0}, {40}}, 1];
have two line segment in the space, how to construct a surface with two line segment as the boundary?
You may do this parametrically.
Supose your two segments described by:
{s1(t)} = t {a1} + {b1} (0 <= t <= 1)
{s2(t)} = t {a2} + {b2} (0 <= t <= 1)
where the {} indicates vector quantities, {a},{b} constants.
Then, for any t you have two points in space, one in each segment.
The straight line between them can be described by:
{r(v)} = ({s2(t)} - {s1(t)}) v + {s1(t)} (0 <= v <= 1 )
We are almost there. Now we write the function describing the surface, replacing s1 and s2 by their values:
{K(v,t)} = t v ( {a2} - {a1} )+ v ({b2} - {b1}) + t {a1} + {b1} (0<= t,v <=1)
HTH!
Edit
An Example:
a1 = {1, 1, 1};
b1 = {0, 0, 0};
a2 = {1, 1, 0};
b2 = {0, 0, 0};
Show[ParametricPlot3D[
t v a1 (a2 - a1) + v (b2 - b1) + t a1 + b1, {t, 0, 1}, {v, 0, 1},
AxesLabel -> {"x", "y", "z"}],
Graphics3D[{Thick, Red, Line[{b1, a1 + b1}]}],
Graphics3D[{Thick, Red, Line[{b2, a2 + b2}]}]]
Another example, showing a non-flat surface:
a1 = {1, 1, 1};
b1 = {0, 0, 1};
a2 = {1, 0, 0};
b2 = {0, 1, 0};
The two line segments will have to be co-planar (ie: both lie on the surface you want to reconstruct). A cross-product of the two line segments will give you the normal to the surface (a vector perpendicular to the surface).
What I'm not sure about at this point is what you mean by the line segments determining the boundary. If the ends of the line segments are the 4 points of a quad boundary and you want to turn that into a subdivided patch, then you can bilinearly interpolate between the corner points to produce the coordinates for your patch mesh.