Opacity control for overlaying plots - graphics

Given two vector plots and a contour plot like the following
as = VectorPlot[{Cos[y], Sin[x] }, {x, -3, 3}, {y, -3, 3},
VectorScale -> Automatic, VectorColorFunction -> "Rainbow"
];
bs = StreamPlot[{Cos[y], Sin[x] }, {x, -3, 3}, {y, -3, 3},
VectorScale -> Automatic, StreamColorFunction -> "Rainbow"
];
cs = ContourPlot[Cos[x] + Sin[y], {x, -3, 3}, {y, -3, 3},
ColorFunction -> "BlueGreenYellow"
];
Show[cs, bs, as]
we can see basic superimposing job is well done by Show[]. But my question is how can I control the opacity of the background contour plot cs? Also, how can I insert "BlueGreenYellow" type color schemes in a color function like the following?
ContourPlot[Cos[x] + Sin[y], {x, -3, 3}, {y, -3, 3},
ColorFunction -> (Directive[Opacity[#],Blue] &)
];

I do not believe that jmlopez' solution is correct, because the vectors and the frame are also partially transparent. I believe that it is better to insert an Opacity command into the Graphics object, which will preserve opaque vectors:
as = VectorPlot[{Cos[y], Sin[x]}, {x, -3, 3}, {y, -3, 3},
VectorScale -> Automatic, VectorColorFunction -> "Rainbow"];
bs = StreamPlot[{Cos[y], Sin[x]}, {x, -3, 3}, {y, -3, 3},
VectorScale -> Automatic, StreamColorFunction -> "Rainbow"];
cs = ContourPlot[Cos[x] + Sin[y], {x, -3, 3}, {y, -3, 3},
ColorFunction -> "BlueGreenYellow"];
cs2 = MapAt[{Opacity[0.5], #} &, cs, 1];
Show[cs2, bs, as]
The second question was never addressed. You can combine opacity and a color gradient like this:
ContourPlot[Cos[x] + Sin[y], {x, -3, 3}, {y, -3, 3},
ColorFunction -> ({Opacity[#], ColorData["BlueGreenYellow"][#]} &)
]

You can try using BaseStyle as follows:
cs = ContourPlot[Cos[x] + Sin[y], {x, -3, 3}, {y, -3, 3},
ColorFunction -> "BlueGreenYellow",
BaseStyle -> Directive[Opacity[0.5]]
];

Related

"outer" in python similar to Mathematica

I have an array of 2D positions (x,y) of a few particles. In Mathematica, I can use
Outer[Subtract, pos, pos, 1]
If pos is an array of shape (n,2) where n is the number of particles, the result of the above Mathematia code is a n x n x 2 array and each [i,j] element of this matrix is the result of (x_i - x_j, y_i - y_j) operation.
For example
pos = {{x1, y1}, {x2, y2}, {x3, y3}};
Outer[Subtract, pos, pos, 1]
gives
{
{{0, 0}, {x1 - x2, y1 - y2}, {x1 - x3, y1 - y3}}
,
{{-x1 + x2, -y1 + y2}, {0, 0}, {x2 - x3, y2 - y3}}
,
{{-x1 + x3, -y1 + y3}, {-x2 + x3, -y2 + y3}, {0, 0}}
}
which is a 3x3x2 array. However, in python I could not get similar results:
import numpy as np
pos = [[1, 2], [5, 6], [8, 9]]
print (np.subtract.outer(pos, pos).shape)
gives (3, 2, 3, 2), and np.subtract.outer(pos, pos) is
array([[[[ 0, -1],
[-4, -5],
[-7, -8]],
[[ 1, 0],
[-3, -4],
[-6, -7]]],
[[[ 4, 3],
[ 0, -1],
[-3, -4]],
[[ 5, 4],
[ 1, 0],
[-2, -3]]],
[[[ 7, 6],
[ 3, 2],
[ 0, -1]],
[[ 8, 7],
[ 4, 3],
[ 1, 0]]]])
while for similar values the Mathemtica code gives what I need, that is
{
{{0, 0}, {-4, -4}, {-7, -7}}
,
{{4, 4}, {0, 0}, {-3, -3}}
,
{{7, 7}, {3, 3}, {0, 0}}
}
you are looking for:
pos = np.array(pos)
pos[:,None]-pos
You can also achieve the same by:
np.squeeze([i-pos for i in pos])
EDIT:
For normalization, you can do:
ss = np.linalg.norm(pos_diff,axis = 2,keepdims = True)
ss[ss==0] = 1
pos_diff/ss
numpy.ufunc.outer(a,b) will calculate each possible combination with one element from a and another from b. One option is to carry out calculations for the x and y coordinates separately and then remerge the result:
pos = np.array([[1, 2], [5, 7], [8, 13]])
dx = np.subtract.outer(pos[:,0],pos[:,0])
dy = np.subtract.outer(pos[:,1],pos[:,1])
result=np.transpose([dx,dy], axes=(1,2,0))
(I changed the values in pos so that the result is less symmetric.)
Edit: As compared to calculating and storing useless x_i-y_j by acting subtract.outer on the whole arrays then using squeeze afterwards, this solution is significantly more effective for large arrays.

Drawing clock face in Mathematica (looking for a better solution)

I am trying to find a general solution for drawing clock face like graphical objects in Mathematica. I've already implemented a version of my own, but I think a much better solution must exist. A neater version with less code or clearer thought process would be appreciated.
My version:
radius = 1;
elementList =
Join[Table[i, {i, 3, 1, -1}], Table[i, {i, 12, 4, -1}]];
elementNumber = Length[elementList];
thetaList = Table[i, {i, 0, 2 Pi, 2 Pi/elementNumber}][[1 ;; 12]];
coordinateList = Map[{radius*Cos[#], radius*Sin[#]} &, thetaList];
objectList =
Map[Style[#, FontFamily -> "Georgia", FontSize -> 30] &,
elementList];
Graphics[
Join[
MapThread[Text[#1, #2] &, {objectList, coordinateList}],
{Circle[{0, 0}, 1.2*radius]}
]
]
Here is one way to make a clock:
clockFace = Import["http://i.imgur.com/ufanv.jpg"];
{hour, minute, second} = Take[Date[], -3];
hour = Mod[hour, 12] + minute/60.;
Graphics3D[
{
{Texture[clockFace],
Polygon[{{-1, -1, 0}, {1, -1, 0}, {1, 1, 0}, {-1, 1, 0}},
VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}
]
},
{Black, AbsoluteThickness[8],
Line[{{0, 0, 0},
.55 {Cos[Pi/2 - 2 Pi hour/12], Sin[Pi/2 - 2 Pi hour/12], 0}}
]
},
{Black, AbsoluteThickness[5],
Line[{{0, 0, 0},
.8 {Cos[Pi/2 - 2 Pi minute/60], Sin[Pi/2 - 2 Pi minute/60], 0}}
]
}
},
Boxed -> False, Lighting -> "Neutral"]
Addition
Here is a rotating, spinning 3D clock for your amusement:
clockFace = Import["http://i.imgur.com/ufanv.jpg"];
vtc = VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
hand[thickness_, radius_, time_] := {AbsoluteThickness[thickness],
Line[{{0, 0, -1}, {radius Cos[Pi/2 + 2 Pi time],
radius Sin[Pi/2 + 2 Pi time], -1}}],
Line[{{0, 0, 1}, {radius Cos[Pi/2 - 2 Pi time],
radius Sin[Pi/2 - 2 Pi time], 1}}],
Line[{{0, -1, 0}, {radius Cos[Pi/2 - 2 Pi time], -1,
radius Sin[Pi/2 - 2 Pi time]}}],
Line[{{0, 1, 0}, {radius Cos[Pi/2 + 2 Pi time], 1,
radius Sin[Pi/2 + 2 Pi time]}}],
Line[{{-1, 0, 0}, {-1, radius Cos[Pi/2 + 2 Pi time],
radius Sin[Pi/2 + 2 Pi time]}}],
Line[{{1, 0, 0}, {1, radius Cos[Pi/2 - 2 Pi time],
radius Sin[Pi/2 - 2 Pi time]}}]};
Dynamic[
{hour, minute, second} = Take[Date[], -3];
hour = Mod[hour, 12] + minute/60.;
Graphics3D[{
{Texture[clockFace],
Polygon[{{1, -1, -1}, {-1, -1, -1}, {-1, 1, -1}, {1, 1, -1}},
vtc],
Polygon[{{-1, -1, 1}, {1, -1, 1}, {1, 1, 1}, {-1, 1, 1}}, vtc],
Polygon[{{-1, 1, -1}, {-1, -1, -1}, {-1, -1, 1}, {-1, 1, 1}},
vtc], Polygon[{{1, -1, -1}, {1, 1, -1}, {1, 1, 1}, {1, -1, 1}},
vtc], Polygon[{{-1, -1, -1}, {1, -1, -1}, {1, -1, 1}, {-1, -1,
1}}, vtc],
Polygon[{{1, 1, -1}, {-1, 1, -1}, {-1, 1, 1}, {1, 1, 1}}, vtc]
}, {Black,
hand[8, .55, hour/12],
hand[5, .8, minute/60],
hand[3, .8, second/60]
}
},
Boxed -> False, Lighting -> "Neutral",
ViewPoint ->
5 {Cos[2 Pi second/60], Sin[2 Pi second/60],
Sin[2 Pi second/30]}, SphericalRegion -> True,
Background -> Black, ImageSize -> Full]] // Deploy
Here's a version of a function that generalizes the generation of clock face to allow you to easily change the style of the numbers, the number of "hours", and the radius of the face:
Options[clockFace] = {FontFamily -> "Georgia", FontSize -> 30};
clockFace[hours_Integer, radius_?NumericQ, opts : OptionsPattern[]] /;
hours > 0 && Im[radius] == 0 && radius > 0 :=
With[{range = Range[12]},
With[{objects =
Style[#,
FilterRules[{opts}, Options[Style]] ~Join~ Options[clockFace]] & /# range,
thetas = Pi/2 - 2 Pi*range/hours},
Graphics[Append[
MapThread[Text[#1, {Cos[#2], Sin[#2]}] &, {objects, thetas}],
Circle[radius*1.2]]]]]
Some things are just Mathematica style issues; for instance,
FilterRules[{opts}, Options[Style]] ~Join~ Options[clockFace]
is just the way to pass the relevant optional arguments to Style while making sure that clockFace's default values are used where relevant, because Mathematica will use the first applicable rule that it finds in a list of rules (and function options are just lists of rules). I also used With to name things, which is why there's that nesting; other people might prefer to use a single Module. Either way, it's always best to make things local variables whenever possible.
The biggest change, though, was generating the list of numbers in order, using Range, and then adjusting the definition of thetas so everything winds up in the right place. I think it's much easier to see what's going on, because the minus sign means you're moving around clockwise and offsetting by Pi/2 makes it clear you're starting at the top of the clock.
The following is a working 3D clock made by easily combining #Arnoud's answer with Christopher's blog entry:
makeHand[fl_, bl_, fw_, bw_] :=
Polygon[{{-bw, -bl, 0.1}, {bw, -bl, 0.1}, {fw, fl, 0.1},
{0, fl + 8 fw, 0.1}, {-fw, fl, 0.1}}/9];
hourHand = makeHand[5, 5/3, .1, .3];
minuteHand = makeHand[7, 7/3, .1, .3];
secondHand = {Red, EdgeForm[Black], makeHand[7, 7/3, .1/2, .3/2]};
clockFace = Import["http://i.imgur.com/ufanv.jpg"];
Graphics3D[{
{Texture[clockFace],
Polygon[{{-1, -1, 0}, {1, -1, 0}, {1, 1, 0}, {-1, 1, 0}},
VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]},
Rotate[hourHand, Dynamic[Refresh[-30 Mod[AbsoluteTime[]/3600, 60] \[Degree],
UpdateInterval -> 60]], {0, 0, 1}],
Rotate[minuteHand, Dynamic[Refresh[-6 Mod[AbsoluteTime[]/60, 60] \[Degree],
UpdateInterval -> 1]], {0, 0, 1}],
Rotate[secondHand, Dynamic[Refresh[-6 Mod[AbsoluteTime[], 60] \[Degree],
UpdateInterval -> 1/20]], {0, 0, 1}]}, Boxed -> False]
Edit
The animation was captured by using Rasterize[] inside a scheduled task!
a = Graphics3D[(* etc etc*)];
b = {};
t = CreateScheduledTask[AppendTo[b, Rasterize#a], {2, 30}];
StartScheduledTask[t];
While[MatchQ[ScheduledTasks[], {ScheduledTaskObject[_, _, _, _,True]}],Pause[1]];
RemoveScheduledTask[ScheduledTasks[]];
Export["c:\\test.gif", b, "DisplayDurations" -> 1]
Mathematica has something called ClockGauge built-in. The possibilities for styling the clock face are endless, as can be seen in the documentation. The bare-bone version looks like this:
ClockGauge[]
Your method is fine. It is just a little messy. Here is my interpretation:
hours = 12;
radius = 1;
thetaList = Rest#Range[2 Pi, 0, -2 Pi/hours] + Pi/2;
coordinateList = radius {Cos##, Sin##} & /# thetaList;
Graphics[{
FontFamily -> "Georgia",
FontSize -> 30,
Text ~MapThread~ {Range#hours, coordinateList},
Circle[{0, 0}, 1.2 radius]
}]

Gradient Fill using Graphics in Mathematica

How could I create the following using Rectangle[] in Graphics[]?
Using Polygon, you can
Graphics[{EdgeForm[Black],
Polygon[{{0, 0}, {3, 0}, {3, 1}, {0, 1}},
VertexColors -> {White, Red, Red, White}]}]
Also:
Graphics[Raster[{Range[100]/100}, ColorFunction -> (Blend[{White, Red}, #] &)],
AspectRatio -> .3,
Frame -> True,
FrameTicks -> None]

Display multiple 2D plots in 3D using Graphics in Mathematica?

Considering the following :
lalist = {{{{1, 1}, 1}, {{3, 3}, 1}, {{5, 5}, 1}},
{{{1, 5}, 1}, {{3, 3}, 1}, {{5, 1}, 1}}}
Row[{
Graphics[{
Opacity[0.5],Red,
Disk ### lalist[[1]]},
Frame -> True],
Graphics[{
Opacity[0.5],Blue,
Disk ### lalist[[2]]},
Frame -> True]}
]
Is it possible that I plot the Blues
Disks "behind" the red ones in a 3 D
plot ?
Below is not what I need :
Like this?
Graphics3D[{{Texture[
Graphics[{Opacity[0.5], Blue, Disk ### lalist[[2]]},
Frame -> True]],
Polygon[{{-1, -1, -1}, {1, -1, -1}, {1, 1, -1}, {-1, 1, -1}},
VertexTextureCoordinates \[Rule] {{0, 0}, {1, 0}, {1, 1}, {0,
1}}]}, {Texture[
Graphics[{Opacity[0.5], Red, Disk ### lalist[[1]]},
Frame -> True]],
Polygon[{{-1, -1, 1}, {1, -1, 1}, {1, 1, 1}, {-1, 1, 1}},
VertexTextureCoordinates \[Rule] {{0, 0}, {1, 0}, {1, 1}, {0,
1}}]}}, Lighting \[Rule] "Neutral"]
Lots of them with opacity .2:
tab = Table[{Opacity \[Rule] .2,
Texture[Graphics[{Opacity[0.5], Blue, Disk ### lalist[[2]]},
Frame -> True]],
Polygon[{{-1, -1, z}, {1, -1, z}, {1, 1, z}, {-1, 1, z}},
VertexTextureCoordinates \[Rule] {{0, 0}, {1, 0}, {1, 1}, {0,
1}}]}, {z, -2, 2, 1}];
plt = Graphics3D[{tab}, Lighting \[Rule] "Neutral"]
and 400 don't seem to be much of a problem in terms of speed (you can easily modify the code above to see it).
EDIT: OK, just to be silly, try this
Dynamic[Graphics3D[{{Texture[#],
Polygon[{{-1, -1, -1}, {1, -1, -1}, {1, 1, -1}, {-1, 1, -1}},
VertexTextureCoordinates \[Rule] {{0, 0}, {1, 0}, {1, 1}, {0,
1}}]}, {Texture[Rotate[#, \[Pi]/2]],
Polygon[{{-1, -1, 1}, {1, -1, 1}, {1, 1, 1}, {-1, 1, 1}},
VertexTextureCoordinates \[Rule] {{0, 0}, {1, 0}, {1, 1}, {0,
1}}]}}, Lighting \[Rule] "Neutral"] &#Binarize[CurrentImage[]]]
which gives
(or something like that), rotatable, updated in real time etc.
See the solution presented on "Lunchtime Playground: Fun with Mathematica" here: http://mathgis.blogspot.com/2009/02/howto-display-2d-plot-in-3d.html
Using transparent textures to render these circles in layers as ACL does is a nice solution, unless one wants to interact with the resulting 3D object. Rendering of 3D objects that contain transparent elements is done in software whereas otherwise it would have been done in hardware:
The 3D renderer uses two different
methods of sorting polygons. For
graphics scenes that include no
transparency, a hardware-accelerated
depth buffer is used. Otherwise, the
renderer uses a binary space partition
tree to split and sort polygons from
any viewpoint. The BSP tree is slower
to create and is not hardware
accelerated, but it provides the most
general ability to support polygons.
On my laptop, interaction with 3D graphics is incredibly slow as soon as transparent objects start to appear.
The solution would be to use 3D disks instead of semi transparent planes with 2D disks in them. Since MMA doesn't have 3D Disks or Circles if you want to do something like that, you have to roll your own. A bare-bones version would be something like:
myDisk[{x_, y_, z_}, r_] :=
Polygon#Table[
{x, y, z} + r {Cos[\[Phi]], Sin[\[Phi]], 0} // N,
{\[Phi], 0, 2 \[Pi], 2 \[Pi]/200}
]
Your layers would then be generated as follows:
Graphics3D[
{
EdgeForm[],
{
Red,
myDisk[{1, 1, 0.5}, 0.5],
myDisk[{0, 0, 0.5}, 0.5],
myDisk[{-1, -1, 0.5}, 0.5]
},
{
Blue,
myDisk[{1, -1, -0.5}, 0.5],
myDisk[{0, 0, -0.5}, -0.5],
myDisk[{-1, 1, -0.5}, 0.5]}
}
]

Vertical alignment of plots in mathematica via GraphicsColumn

I have an annoying problem using GraphicsColumn() in Mathematica to combine several DateList plots in a single column. I need them to be correctly aligned as they display different timeseries for the same period, but as it turns out the size of the frame of each plot gets automatically resized depending on the length of the Y-axis labels. So combining a plot with 5-figure labels and one with 2-figure labels will totally jeopardise the vertical alignment. I tried several tweaks (e.g. setting width or max width via ImageSize), unfortunately they all seem to apply to the size of the graphic as a whole, not the actual frame. I don't seem to find a way to control the size of the frame itself. Any ideas?
I suspect you want to set the ImagePadding option:
GraphicsColumn[{
Plot[Sin[x], {x, 0, 2 Pi}, ImagePadding -> 20, AxesLabel -> {"x", "very very loooooooong"}],
Plot[Sin[x], {x, 0, 2 Pi}, ImagePadding -> 20, AxesLabel -> {"x", "shrt"}]
}]
I am not sure how you are labeling the graph, but this method should work if you set the value high enough to show the whole label.
You could try the the LevelScheme Multipanel command.
Here's the example given in their documentation and LevelSchemeExamples.nb:
Figure[
{ScaledLabel[{0.5, 1}, "Lissajous curves", FontSize -> 18, Offset -> {0, 1}],
Multipanel[{{0, 1}, {0, 1}}, {2, 2},
XPlotRanges -> {{-1.5, 1.5}, {-Pi/2, 8*Pi + Pi/2}},
YPlotRanges -> {-1.5, 1.5},
XFrameLabels -> {textit["x"], textit["t"]}, BufferB -> 2.5,
YFrameLabels -> textit["y"], BufferL -> 3,
TickFontSize -> 10,
XFrameTicks -> {LinTicks[-2, 2, 1, 5], LinTicks[-Pi, 9*Pi, Pi, 4,
TickLabelFunction -> (Rationalize[#/Pi]*Pi &)]},
YFrameTicks -> LinTicks[-2, 2, 1, 5],
XPanelSizes -> {1, 2.5}, XGapSizes -> {0.1},
YPanelSizes -> {1, 1}, YGapSizes -> {0.1},
Background -> Wheat, PanelLetterBackground -> Wheat
],
FigurePanel[{1, 1}],
RawGraphics[ParametricPlot[{Cos[1*t], Cos[1*t - Pi/2]}, {t, 0, 2*Pi}]],
FigurePanel[{1, 2}],
RawGraphics[Plot[Cos[1*t], {t, 0, 8*Pi}], Dashing -> Automatic],
RawGraphics[Plot[Cos[1*t - Pi/2], {t, 0, 8*Pi}]],
FigurePanel[{2, 1}, PanelLetterBackground -> None],
RawGraphics[ParametricPlot[{Cos[1*t], Cos[4*t - Pi/2]}, {t, 0, 2*Pi}]],
FigurePanel[{2, 2}],
RawGraphics[Plot[Cos[1*t], {t, 0, 8*Pi}], Dashing -> Automatic],
RawGraphics[Plot[Cos[4*t - Pi/2], {t, 0, 8*Pi}]],
},
PlotRange -> {{-0.1, 1.1}, {-0.1, 1.1}},
ImageSize -> 72*2*{3.6, 2.1}
]

Resources