Not sure if this is a MMA bug or me doing something wrong.
Consider the following function:
plotTrace[points_] :=
ListPlot[points,
Joined -> True,
PlotMarkers -> Table[i, {i, Length#points}]]
now consider passing it values generated by RandomReal. Namely, consider
RandomReal[1, {nTraces, nPointsPerTrace, 2(*constant = nDimensions*)}].
If nTraces is 1, then PlotMarkers are displayed for all values of nPointsPerTrace that I tried:
Manipulate[
plotTrace[RandomReal[1, {1, nPointsPerTrace, 2}]],
{nPointsPerTrace, 1, 20, 1}]
If nTraces is 3 or greater, then plot markers are displayed for all values of nPointsPerTrace that I tried
Manipulate[plotTrace[RandomReal[1, {nTraces, nPointsPerTrace, 2}]],
{nTraces, 3, 20, 1}, {nPointsPerTrace, 1, 20, 1}]
But if nTraces is exactly 2, I don't see plot markers, no matter the value of nPointsPerTrace:
Manipulate[plotTrace[RandomReal[1, {2, nPointsPerTrace, 2}]],
{nPointsPerTrace, 1, 20, 1}]
Hints, clues, advice would be greatly appreciated!
It's treating PlotMarkers -> {1,2} as a marker and size, instead of as two markers:
In[137]:= ListPlot[{{1, 2, 3}, {4, 5, 6}}, PlotMarkers -> {1, 2}] // InputForm
Out[137]//InputForm=
Graphics[GraphicsComplex[{{1., 1.}, {2., 2.}, {3., 3.}, {1., 4.}, {2., 5.}, {3., 6.},
{1., 1.}, {2., 2.}, {3., 3.}, {1., 4.}, {2., 5.}, {3., 6.}},
{{{Hue[0.67, 0.6, 0.6], Inset[Style[1, FontSize -> 2], 7],
Inset[Style[1, FontSize -> 2], 8], Inset[Style[1, FontSize -> 2], 9]},
{Hue[0.9060679774997897, 0.6, 0.6], Inset[Style[1, FontSize -> 2], 10],
Inset[Style[1, FontSize -> 2], 11], Inset[Style[1, FontSize -> 2], 12]}, {}}}],
{AspectRatio -> GoldenRatio^(-1), Axes -> True, AxesOrigin -> {0, 0},
PlotRange -> {{0, 3.}, {0, 6.}}, PlotRangeClipping -> True,
PlotRangePadding -> {Scaled[0.02], Scaled[0.02]}}]
Things get even stranger when you try different things for PlotMarkers. The following does not display the plot markers, as in your examples above.
pts = RandomReal[1, {2, 10, 2}];
(* No markers *)
ListPlot[pts,
Joined -> True,
PlotMarkers -> {1, 2}
]
However, when you change the 2 to b, it does:
pts = RandomReal[1, {2, 10, 2}];
(* Has markers *)
ListPlot[pts,
Joined -> True,
PlotMarkers -> {1, b}
]
If you try to change the 1 to something, it doesn't work:
pts = RandomReal[1, {2, 10, 2}];
(* No markers *)
ListPlot[pts,
Joined -> True,
PlotMarkers -> {a, 2}
]
It does indeed sound like a bug, but I'm not sure if this is version dependent or some behavior that's not obvious.
Related
I want to make a mathematica plot with no visible y-axis, but retaining the tick labels.
I've tried AxesStyle -> {Thickness[.001], Thickness[0]} with no effect, and setting the opacity to 0 also makes the tick labels fully transparent (and thus invisible).
Any help would be very much appreciated...
p = Plot[Sin[x], {x, 0, 6 Pi},
AxesStyle -> {Black, Opacity[0]},
TicksStyle -> Directive[Opacity[1], Black]]
ticks = AbsoluteOptions[p, Ticks];
ticks[[1, 2, 2]] = DeleteCases[ticks[[1, 2, 2]], {_, "", __}];
ticks[[1, 2, 2, All, 3]] = ConstantArray[{0, 0},
Length[ticks[[1, 2, 2, All, 3]]]];
ticks[[1, 2, 2, All, 2]] = Map[ToString,
ticks[[1, 2, 2, All, 2]]] /. a_String :>
If[StringTake[a, -1] == ".", a <> "0", a];
Plot[Sin[x], {x, 0, 6 Pi},
AxesStyle -> {Black, Directive[Opacity[0], Red]},
TicksStyle -> Directive[Opacity[1], Black],
Ticks -> {Automatic, ticks[[1, 2, 2]]}]
To get the exact original ticks you can use
Cases[Charting`FindTicks[{0, 1}, {0, 1}] ## PlotRange[p][[2]], {_, _}]
{{-1.,-1.0},{-0.5,-0.5},{0.,0},{0.5,0.5},{1.,1.0}}
as implemented here:
p = Plot[Sin[x], {x, 0, 6 Pi},
AxesStyle -> {Automatic, Opacity[0]},
TicksStyle -> Opacity[1]];
ticks = AbsoluteOptions[p, Ticks];
onestyledtick = ticks[[1, 2, 2, 1]];
labels = Cases[Charting`FindTicks[{0, 1}, {0, 1}] ##
PlotRange[p][[2]], {_, _}];
yticks = Map[Join[#, {{0, 0}},
Take[onestyledtick, -1]] &, labels];
Plot[Sin[x], {x, 0, 6 Pi},
AxesStyle -> {Automatic, Opacity[0]},
TicksStyle -> Opacity[1],
Ticks -> {Automatic, yticks}]
I am trying to plot a few points on the following picture in Mathematica:
ParametricPlot3D[
{{u, v, (Cos[u] + Cos[v])/3}, {u, -1, (Cos[u] + Cos[0])/3},
{5, v, (Cos[4] + Cos[v])/3}}, {u, -4, 4}, {v, 0, 8}, Axes -> False,
Boxed -> False, BoxRatios -> {8, 8, 1.5}]
(they should just look like dots on the surface)
What I was trying to do is enter the coordinates of the points manually on another graph using ListPointPlot3D, and then combine them using Show. But for some reason that isn't working. Suggestions?
Also, I would like to add small vectors tangent to the surface in the x directions for the points I have plotted, but I have no idea on how to do that, so suggestions would be very much appreciated!
Perhaps this will help you get started on a solution. It plots 3 random points on the surface. You can change the number of points by setting nPoints. I don't know how to plot tangents along x. But when you figure that out you can use Arrows, as suggested by #Verbeia.
nPoints = 3;
Show[ParametricPlot3D[{
{u, v, (Cos[u] + Cos[v])/3},
{u, -1, (Cos[u] + Cos[0])/3}, {5, v, (Cos[4] + Cos[v])/3}},
{u, -4, 4}, {v, 0, 8}, Axes -> False,
Boxed -> False, BoxRatios -> {8, 8, 1.5},
PlotStyle -> Directive[Opacity[0.5]]],
Graphics3D[{Red, PointSize[.025],
Point[Table[{u1 = RandomReal[{-3, 3}], v1 = RandomReal[{1, 7}],
(Cos[u1] + Cos[v1])/3}, {nPoints}]]}]]
Edit
The following dynamic variation makes use of #belisarius 's contribution:
Manipulate[
Show[ParametricPlot3D[{{u, v, (Cos[u] + Cos[v])/3} },
{u, -4, 4}, {v, 0, 8}, Axes -> False, Boxed -> False,
BoxRatios -> {8, 8, 1.5},
Mesh -> None,
ImageSize -> {400, 300},
PlotRange -> {{-4, 4}, {0, 8}},
PlotRangePadding -> {{0, 1.4}, {0, 0}},
PlotStyle -> Directive[Opacity[0.5]]],
Graphics3D[({Red, PointSize[.025],
Point#f[pt[[1, 1]], pt[[1, 2]]], Black,
Arrow[{f[pt[[1, 1]], pt[[1, 2]]],
f[pt[[1, 1]], pt[[1, 2]]] + D[f[t, pt[[1, 2]]], t] /.
t -> pt[[1, 1]]}]}]],
Grid[{{
LocatorPane[Dynamic[pt],
Dynamic[Graphics[{},
PlotRange -> {{-4, 4}, {0, 8}},
Frame -> True,
ImageSize -> 160,
FrameTicks -> {Range[-4, 4], Range[0, 8], None, None},
FrameLabel -> {"u", "v"},
GridLines -> {Range[-4, 4], Range[0, 8]},
GridLinesStyle -> Directive[LightGray]]],
{{-4, 0}, {4, 8}}]}}],
{{pt, {{1, 2}}}, ControlType -> None},
Initialization :> {f[u_, v_] := {u, v, (Cos[u] + Cos[v])/3};}]
For the Arrows
f[u_, v_] := {u, v, (Cos[u] + Cos[v])/3};
Show[ParametricPlot3D[{f[u, v]}, {u, -4, 4}, {v, 0, 8},
Axes -> False, Mesh -> None, Boxed -> False, BoxRatios -> {8, 8, 1.5},
PlotStyle -> Directive[Opacity[0.5]]],
Graphics3D#
Table[{Red, PointSize[.025], Point#f[u, v],
Black, Arrow[{f[u, v], f[u, v] + D[f[t, v], t] /. t -> u}]},
{u, -4, 4, 2}, {v, 0, 8, 2}]]
For getting the arrows in any direction a = { a1, a2 } instead of x, you may do:
Dot[{a1,a2}.#] & /# D[f[u, v], {{u, v}}]
(*
-> {a1, a2, -(1/3) a1 Sin[u] - 1/3 a2 Sin[v]}
*)
Edit
Both derivatives and normal:
f[u_, v_] := {u, v, (Cos[u] + Cos[v])/3};
Show[
Graphics3D#
Table[{Red, PointSize[.025], Point#f[u, v], Black, Arrowheads[.02],
Arrow[{f[u, v], f[u, v] + D[f[t, v], t] /. t -> u}],
Arrow[{f[u, v], f[u, v] + D[f[u, t], t] /. t -> v}],
Arrow[{f[u, v], f[u, v] +
Cross[D[f[t, v], t] /. t -> u,
D[f[u, t], t] /. t -> v]}]},
{u, -4, 4, 2}, {v, 0, 8, 2}],
ParametricPlot3D[{f[u, v]}, {u, -4, 4}, {v, 0, 8},
Axes -> False, Mesh -> 3, MeshStyle -> {{Opacity[0.1], LightBlue}},
Boxed -> False, BoxRatios -> {8, 8, 1.5},
PlotStyle -> Directive[Opacity[0.5]]]]
You can combine the plot with points using Graphics3D[listofpoints], where listofpoints is a T*3 matrix list, and the arrows using constructs like Graphics3D[Arrow[{{1, 1, -1}, {2, 2, 0}, {3, 3, -1}, {4, 4, 0}}]]. If they are all Graphics3D objects, you should be able to combine them with Show.
Sorry, I am not near a Mathematica installation to provide you with an example just now.
I have a set of points given by this list:
list1 = {{3, 1}, {1, 3}, {-1, 2}, {-1, -1}, {1, -2}};
I would like Mathematica to draw a line from the origin to all the points above. In other words draw vectors from the origin (0,0) to all the individual points in the above set. Is there a way to do this? So far I've tried the Filling option, PlotPoints and VectorPlot but they don't seem to be able to do what I want.
Starting easy, and then increasing difficulty:
Graphics[{Arrow[{{0, 0}, #}] & /# list1}]
Graphics[{Arrow[{{0, 0}, #}] & /# list1}, Axes -> True]
Needs["PlotLegends`"];
list1 = {{3, 1}, {1, 3}, {-1, 2}, {-1, -1}, {1, -2}};
k = ColorData[22, "ColorList"][[;; Length#list1]];
GraphicsRow[{
Graphics[Riffle[k, Arrow[{{0, 0}, #}] & /# #], Axes -> True],
Graphics#Legend[Table[{k[[i]], #[[i]]}, {i, Length##}]]}] &#list1
Needs["PlotLegends`"];
list1 = {{3, 1}, {1, 3}, {-1, 2}, {-1, -1}, {1, -2}};
k = ColorData[22, "ColorList"][[;; Length#list1]];
ls = Sequence[Thick, Line[{{0, 0}, {1, 0}}]];
GraphicsRow[{
Graphics[Riffle[k, Arrow[{{0, 0}, #}] & /# #], Axes -> True],
Graphics#Legend[MapThread[{Graphics[{#1, ls}], #2} &, {k, #}]]}] &#list1
Needs["PlotLegends`"];
list1 = {{3, 1}, {1, 3}, {-1, 2}, {-1, -1}, {1, -2}};
pr = {Min##, Max##} & /# Transpose#list1;
k = ColorData[22, "ColorList"][[;; Length#list1]];
GraphicsRow[{
Graphics[r = Riffle[k, {Thick,Arrow[{{0, 0}, #}]} & /# #], Axes -> True],
Graphics#
Legend[MapThread[
{Graphics[#1, Axes -> True, Ticks -> None, PlotRange -> pr],
Text#Style[#2, 20]} &,
{Partition[r, 2], #}]]}] &#list1
You could also tweak ListVectorPlot, although I don't see why you should do it, as it is not intended to use like this:
list1 = {{3, 1}, {1, 3}, {-1, 2}, {-1, -1}, {1, -2}};
data = Table[{i/2, -i/Norm[i]}, {i, list1}];
ListVectorPlot[data, VectorPoints -> All,
VectorScale -> {1, 1, Norm[{#1, #2}] &},
VectorStyle -> {Arrowheads[{-.05, 0}]}]
Graphics[
{
Line[{{0, 0}, #}] & /# list1
}
]
where /# is the shorthand infix notation for the function Map.
I wonder why you tried Filling, Plotpoints and VectorPlot. I must assume you haven't read the documentation at all, because even a superficial reading would tell you that those commands and options have nothing to do with the functionality you're looking for.
What is the simplest way to create a row/column/grid of plots, with the whole grid having a single FrameLabel?
I need something similar to this:
p := ListPlot[RandomInteger[10, 5], Joined -> True, Axes -> False,
Frame -> True, PlotRange -> {0, 11},
FrameLabel -> {"horizontal", None}, AspectRatio -> 1]
GraphicsRow[{Show[p, FrameLabel -> {"horizontal", "vertical"}], p, p}]
For a row format, it could have one or multiple horizontal labels, but only one vertical one.
Issues to consider:
Vertical scale must match for all plots, and must not be ruined by e.g. a too long label or automatic PlotRangePadding.
Good (and resize-tolerant!) control of inter-plot spacing is needed (after all, this is one of the motivations behind removing the redundant labels)
General space-efficiency of the arrangement. Maximum content, minimum (unnecessary) whitespace.
EDIT
I'm trying to be able to robustly create print ready figures, which involves a lot of resizing. (Because the exported PDFs will usually not have the same proportions as what I see in the notebook, and must have readable but not oversized fonts)
You can use LevelScheme to achieve what you want. Here's an example:
<< "LevelScheme`"
Figure[{
Multipanel[{{0, 1}, {0, 1}}, {1, 3},
XFrameLabels -> textit["x"], BufferB -> 3,
YFrameLabels -> textit["Sinc(x)"], BufferL -> 3,
TickFontSize -> 9,
XGapSizes -> {0.1, 0.1},
PanelLetterCorner -> {1, 1}
],
FigurePanel[{1, 1}, PlotRange -> {{-1.6, -0.6}, {-0.5, 1}}],
RawGraphics[Plot[Sinc[20 x], {x, -1.6, -0.6}]],
FigurePanel[{1, 2}, PlotRange -> {{-0.5, 0.5}, {-0.5, 1}}],
RawGraphics[Plot[Sinc[20 x], {x, -0.5, 0.5}]],
FigurePanel[{1, 3}, PlotRange -> {{0.6, 1.6}, {-0.5, 1}}],
RawGraphics[Plot[Sinc[20 x], {x, 0.6, 1.6}]]
},
PlotRange -> {{-0.1, 1.02}, {-0.12, 1.095}}]
LevelScheme offers you tremendous flexibility in the arrangement of your plot.
Instead of naming giving the plot common labels, you can move the definition inside the FigurePanel[] and control the labels for each one individually.
You can set inter-plot spacings both in the X and Y directions and also change the sizes of each panel, for e.g., the left one can take up 2/3 of the space and the next two just 1/6 of the space each.
You can set individual plot ranges, change the frame tick labels for each, control which side of the panel (top/bottom/l/r) the labels should be marked, change panel numberings, etc.
The only drawback is that you might have to wrestle with it in some cases, but in general, I've found it a pleasure to use.
EDIT
Here's one similar to your example:
Figure[{
Multipanel[{{0, 1}, {0, 1}}, {1, 3},
YFrameLabels -> textit["Vertical"], BufferL -> 3,
TickFontSize -> 9,
XGapSizes -> {0.1, 0.1},
PanelLetterCorner -> {1, 1}
],
FigurePanel[{1, 1}, PlotRange -> {{1, 10}, {0, 10}}],
RawGraphics[ListLinePlot[RandomInteger[10, 10]]],
FigurePanel[{1, 2}, PlotRange -> {{1, 10}, {0, 10}},
LabB -> textit["Horizontal"], BufferB -> 3],
RawGraphics[ListLinePlot[RandomInteger[10, 10]]],
FigurePanel[{1, 3}, PlotRange -> {{1, 10}, {0, 10}}],
RawGraphics[ListLinePlot[RandomInteger[10, 10]]]
},
PlotRange -> {{-0.1, 1.02}, {-0.2, 1.095}}]
EDIT 2
To answer Mr. Wizard's comment, here's a blank template for a 2x3 grid
Figure[{Multipanel[{{0, 1}, {0, 1}}, {2, 3},
XFrameTicks -> None,
YFrameTicks -> None,
XGapSizes -> {0.1, 0.1},
YGapSizes -> {0.1}],
FigurePanel[{1, 1}],
FigurePanel[{1, 2}],
FigurePanel[{1, 3}],
FigurePanel[{2, 1}],
FigurePanel[{2, 2}],
FigurePanel[{2, 3}]
}, PlotRange -> {{-0.01, 1.01}, {-0.01, 1.01}}]
And here's one with extended panels
Figure[{Multipanel[{{0, 1}, {0, 1}}, {2, 3},
XFrameTicks -> None,
YFrameTicks -> None,
XGapSizes -> {0.1, 0.1},
YGapSizes -> {0.1}],
FigurePanel[{1, 1}, PanelAdjustments -> {{0, 0}, {1.1, 0}}],
FigurePanel[{1, 2}],
FigurePanel[{1, 3}],
FigurePanel[{2, 2}, PanelAdjustments -> {{0, 1.1}, {0, 0}}]
}, PlotRange -> {{-0.01, 1.01}, {-0.01, 1.01}}]
You already know how to handle multiple horizontal labels through ListPlot.
You can get single labels by using Panel. For example...
p := ListPlot[RandomInteger[10, 5], Joined -> True, Axes -> False,
Frame -> True, PlotRange -> {0, 11}, AspectRatio -> 1]
Panel[GraphicsRow[{p, p, p}], {"horizontal",Rotate["vertical", Pi/2]},
{Bottom, Left}, Background -> White]
You can optionally include labels on Top and Right edges too.
Here is one option I just put together. Its advantage is that it is simple.
I like the look of yoda's LevelScheme plots better, assuming those can be done for a grid as well.
p := ListPlot[RandomInteger[10, 5], Joined -> True, Axes -> False,
Frame -> True, PlotRange -> {0, 11}, AspectRatio -> 1]
gg = GraphicsGrid[{{p, p, p}, {p, p, p}, Graphics /# Text /# {"Left", "Center", "Right"}},
Spacings -> 5, ItemAspectRatio -> {{1, 1, 0.15}}];
Labeled[gg, Rotate["vertical", Pi/2], Left]
When I run the following code
pMin = {-3, -3};
pMax = {3, 3};
range = {pMin, pMax};
Manipulate[
GraphicsGrid[
{
{Graphics[Locator[p], PlotRange -> range]},
{Graphics[Line[{{0, 0}, p}]]}
}, Frame -> All
],
{{p, {1, 1}}, Locator}
]
I expect the Locator control to be within the bounds of the first Graph, but instead it can be moved around the whole GraphicsGrid region. Is there an error in my code?
I also tried
{{p, {1, 1}}, pMin, pMax, Locator}
instead of
{{p, {1, 1}}, Locator}
But it behaves completely wrong.
UPDATE
Thanks to everyone, this is my final solution:
Manipulate[
distr1 = BinormalDistribution[p1, {1, 1}, \[Rho]1];
distr2 = BinormalDistribution[p2, {1, 1}, \[Rho]2];
Grid[
{
{Graphics[{Locator[p1], Locator[p2]},
PlotRange -> {{-5, 5}, {-5, 5}}]},
{Plot3D[{PDF[distr1, {x, y}], PDF[distr2, {x, y}]}, {x, -5, 5}, {y, -5, 5}, PlotRange -> All]}
}],
{{\[Rho]1, 0}, -0.9, 0.9}, {{\[Rho]2, 0}, -0.9, 0.9},
{{p1, {1, 1}}, Locator},
{{p2, {1, 1}}, Locator}
]
UPDATE
Now the problem is that I cannot resize and rotate the lower 3d graph. Does anyone know how to fix that?
I'm back to the solution with two Slider2D objects.
If you examine the InputForm you'll find that GraphicsGrid returns a Graphics object. Thus, the Locator indeed moves throughout the whole image.
GraphicsGrid[{{Graphics[Circle[]]}, {Graphics[Disk[]]}}] // InputForm
If you just change the GraphicsGrid to a Grid, the locator will be restricted to the first part but the result still looks a bit odd. Your PlotRange specification is a bit strange; it doesn't seem to correspond to any format specified in the Documentation center. Perhaps you want something like the following.
Manipulate[
Grid[{
{Graphics[Locator[p], Axes -> True,
PlotRange -> {{-3, 3}, {-3, 3}}]},
{Graphics[Line[{{0, 0}, p}], Axes -> True,
PlotRange -> {{-3, 3}, {-3, 3}}]}},
Frame -> All],
{{p, {1, 1}}, Locator}]
LocatorPane[] does a nice job of confining the locator to a region.
This is a variation on the method used by Mr. Wizard.
Column[{ LocatorPane[Dynamic[pt3],
Framed#Graphics[{}, ImageSize -> 150, PlotRange -> 3]],
Framed#Graphics[{Line[{{-1, 0}, Dynamic#pt3}]}, ImageSize -> {150, 150},
PlotRange -> 3]}]
I would have assumed that you'd want the locator to share the space with the line it controls. In fact, to be "attached" to the line. This turns out to be even easier to implement.
Column[{LocatorPane[Dynamic[pt3],Framed#Graphics[{Line[{{-1, 0}, Dynamic#pt3}]},
ImageSize -> 150, PlotRange -> 3]]}]
I am not sure what you are trying to achieve. There are a number of problems I see, but I don't know what to address. Perhaps you just want a simple Slider2D construction?
DynamicModule[{p = {1, 1}},
Column#{Slider2D[Dynamic[p], {{-3, -3}, {3, 3}},
ImageSize -> {200, 200}],
Graphics[Line[{{0, 0}, Dynamic[p]}],
PlotRange -> {{-3, 3}, {-3, 3}}, ImageSize -> {200, 200}]}]
This is a reply to the updated question about 3D graphic rotation.
I believe that LocatorPane as suggested by David is a good way to approach this. I just put in a generic function since your example would not run on Mathematica 7.
DynamicModule[{pt = {{-1, 3}, {1, 1}}},
Column[{
LocatorPane[Dynamic[pt],
Framed#Graphics[{}, PlotRange -> {{-5, 5}, {-5, 5}}]],
Dynamic#
Plot3D[{x^2 pt[[1, 1]] + y^2 pt[[1, 2]],
-x^2 pt[[2, 1]] - y^2 pt[[2, 1]]},
{x, -5, 5}, {y, -5, 5}]
}]
]