I have a samples list with a collection of (x,y) coordinates pairs. I want to use plot2d to create a discrete plot from these points, not showing lines connecting each point.
This is my script:
plot2d(
[discrete, samples],
[style, [points, 1, 5, 1]],
[legend, "Samples"],
[gnuplot_term, "svg size 640,480"],
[gnuplot_out_file, "graph_samples.svg"]
)$
But the result is a plot with connected points, as can be seen in the picture below. Despite the use of the [style, [points, 1, 5, 1]] option, the plot connects each point. The style definition seems to be ignored.
Does anyone have a clue why is this happening? I know I could alternatively use draw2d but I'd rather use plot2d if possible.
You can also quote a symbol to prevent evaluation:
points: [1, 2, 3];
x: 42;
plot2d('x^2, ['x, 1, 2], ['style, 'points]);
The problem was that I had a points matrix previously declared that was conflicting with the style definition. Changed its name and worked like a charm.
Related
I'm given a dictionary with keys(ids) and values.
> Dict{Int64, Vector{Float64}} with 122 entries:
3828 => [1, 2, 3, 4...
2672 => [6,7,5,8...
...
Now I need to apply umap on it. I have the code that
embedding = umap(mat, 2; n_neighbors=15, min_dist=0.001, n_epochs=200)
println(size(embedding))
Plots.scatter(embedding[1,:],embedding[2,:])
Here mat is the matrix
1, 2, 3, 4
6, 7, 5, 8
....
So I got the embedding matrix and the umap plot. But in the plot all points are same color and no labels. How do I do so that I can get points with labels(keys in the dictionary)?
Looking at UMAP.jl, the input matrix should have the shape (n_features x n_samples). If each entry in your dictionary is a sample and I’m interpreting your matrix notation correctly, it appears you have this reversed.
You should be able to add the keys of the dictionary as annotations to the plot as follows (potentially with an optional additional offset to each coordinate):
Plots.annotate!(
embedding[1,:] .+ x_offset,
embedding[2,:] .+ y_offset,
string.(collect(keys(yourdict)))
)
Finally, I’m not sure what variable you actually want to map to the color of the markers in the scatterplot. If it’s the integer value of the keys you should pass this to the scatter function just like above except without turning them into strings.
I wanted to plot a user-defined Piecewise function (pagoda function) in Mathematica 10.2.
It seems straightforward to me unfortunately the easy command leads to a bad result.
My first approach was:
f[x_] := Piecewise[{{0, x <= -1}, {-Abs[x] + 1, -1 < x < 1}, {0,
x >= 1}}]
Plot3D[ 5*f[x]*f[y], {x, -1.5, 1.5}, {y, -1.5, 1.5}]
I also tried to set MaxRecursion which lead to more terrible results in a few cases (e.g. 2,3).
Can anybody tell me how to plot this function in a smooth nice way?
Thanks,
Felix
As far as I can remember, making visible gaps was introduced as a feature. Before that, piecewise or discontinuous functions were plotted like this:
Plot[Piecewise[{{x, x <= 1}, {3, x > 1}}], {x, 0, 3}, Exclusions -> None]
That behavior gives the wrong impression. I would have to check when this was default or if I'm completely off here. Anyway, as already noted in the comments, you can use the Exclusions option to get connected graphs.
You don't need to increase PlotPoints because Mathematica will (hopefully always) recognize the boundaries of the pieces as places where it needs to recursively increase points. Therefore, the MaxRecursion option is far more important to give a smooth plot. This example was rendered with only 10 points, but a recursion value of 5:
Therefore, your function renders extremely well even with 10 plot-points when the recursion is high enough. Look how many subdivisions you get on the cracks
Plot3D[5*f[x]*f[y], {x, -1.5, 1.5}, {y, -1.5, 1.5}, PlotRange -> All,
Exclusions -> None, PlotPoints -> 10, MaxRecursion -> 6, Mesh -> All]
Finally, note that the gaps are not restricted to Piecewise functions. As you can verify yourself, UnitStep will also show gaps. You can try it with your example by using an undocumented function to turn everything to UnitStep:
Simplify`PWToUnitStep[5*f[x]*f[y]]
(*
5 (1 - Abs[x]) (1 - Abs[y]) (1 - UnitStep[-1 - x]) (1 -
UnitStep[-1 + x]) (1 - UnitStep[-1 - y]) (1 - UnitStep[-1 + y])
*)
With all due respect to #halirutan, by itself MaxRecursion set to 6 was not enough in the following plot to adjust the peak values of a piecewise function to be a monotonic increasing sequence:
This improved, when, in addition, I set PlotPoints to 240, as follows.
However, that does not completely solve all the display problems. For example, note in the plots above, that the initial value y = 0, is not correctly plotted as a blue vertical line despite use of Exclusions->None. Moreover, the grid lines, which are Dotted, do not display as dots, but as dashes which run off below the x-axis. All of these problems can be solved, probably more efficiently, by generating the points or dots as list data and using ListPlot or, as in this case ListLogPlot and using Joined->True when appropriate. That is low level solution, but is needed in more complicated plots to obtain a plot with shorter run time and more accessible control over the display features.
Somewhat inexplicably, the length parameter in arrows is specified in inches (from ?arrows):
length length of the edges of the arrow head (in inches).
R source even goes so far as to explicitly make note that this measurement is in inches in a comment, highlighting how peculiar this design is.
That means the relative size of the arrows depends on dev.size(). What's not clear is how to translate inches into axis units (which are infinitely more useful in the first place). Here's a simplified version:
h = c(1, 2, 3)
xs = barplot(h, space = 0, ylim = c(0, 4))
arrows(xs, h - .5, xs, h + .5,
length = .5*mean(diff(xs)))
How this displays will depend on the device. E.g. here is the output on this device:
png('test.png', width = 5, height = 5)
And here it is on another:
png('test.png', width = 8, height = 8)
It's a bit of an optical illusion to tell on sight, but the arrows are indeed the same width in the two plots. How can I control this so that both plots (which convey the same data) display identically? More specifically, how can I make sure that the arrows are exactly .5 plot units in width?
I spent far too much time in the rabbit hole on this, but here goes. I'll document a bit of my journey first to aid others who happen upon this in the types of nooks and crannies to search when trying to pull yourself up by your bootstraps.
I started looking in the source of arrows, but to no avail, since it quickly dives into internal code. So I searched the R source for "C_arrows" to find what's happening; luckily, it's not too esoteric, as far as R internal code goes. Poking around it seems the workhorse is actually GArrow, but this was a dead end, as it seems the length parameter isn't really transformed there (IIUC this means the conversion to inches is done for the other coordinates and length is untouched). But I happened to notice some GConvert calls that looked closer to what I want and hoped to find some user-facing function that appeals to these directly.
This led me to go back to R and to simply run through the gamut of functions in the same package as arrows looking for anything that could be useful:
ls(envir = as.environment('package:grDevices'))
ls(envir = as.environment('package:graphics'))
Finally I found three functions in graphics: xinch, yinch, and xyinch (all found on ?xinch) are used for the opposite of my goal here -- namely, they take inches and convert them into device units (in the x, y, and x&y directions, respectively). Luckily enough, these functions are all very simple, e.g. the work horse of xinch is the conversion factor:
diff(par("usr")[1:2])/par("pin")[1L]
Examining ?par (for the 1,000,000th time), indeed pin and usr are exactly the graphical parameter we need (pin is new to me, usr comes up here and there):
pin The current plot dimensions, (width, height), in inches.
usr A vector of the form c(x1, x2, y1, y2) giving the extremes of the user coordinates of the plotting region.
Hence, we can convert from plot units to inches by inverting this function:
xinch_inv = function(dev_unit) {
dev_unit * par("pin")[1L]/diff(par("usr")[1:2])
}
h = c(1, 2, 3)
xs = barplot(h, space = 0, ylim = c(0, 4))
arrows(xs, h - .5, xs, h + .5,
# just convert plot units to inches
length = xinch_inv(.5*mean(diff(xs))))
Resulting in (5x5):
And (8x8):
One further note, it appears length is the length of each side of the arrow head -- using length = xinch_inv(.5), code = 3, angle = 90 results in segments as wide as the bars (i.e., 1).
On the off chance you're interested, I've packaged these in my package as xdev2in, etc.; GitHub only for now.
I have been using rgl to plot a block model - using shade3d to render the blocks.
I'd like to replace certain blocks using an interactive process. The problem is the rendering is cumulative, so if I overlay a white cube with alpha 0.5 on a blue cube with alpha 1, I'll still see the blue cube. [see below]. I looked at clear3d, but seems to only work at a global level. Any ideas?
shade3d(translate3d(cube3d(),
1,
1,
1),
col="blue",
alpha = 1)
After some work:
shade3d(translate3d(cube3d(),
1,
1,
1),
col="white",
alpha = 0.5)
clear3d() removes all objects, as you've discovered. To remove a single object, you want rgl.pop().
As long as you know a given shape's object ID (i.e. its position on the stack of plotted objects), you can use rgl.pop() to remove it. The key bookkeeping detail, then, is that you must keep track of the object ID of any object you may later want to remove.
(Conveniently, most rgl functions whose side-effect is to draw an object to the rgl device return the object ID (or vector of IDs) as their return value. Alternatively, use rgl.ids() to access the object IDs of all objects plotted on the current device.)
A few more details from ?rgl.pop:
RGL holds two stacks. One is for shapes and the other is for
lights. 'clear3d' and 'rgl.clear' clear the specified stack, or
restore the defaults for the bounding box (not visible) or
viewpoint. By default with 'id=0' 'rgl.pop' removes the top-most
(last added) node on the shape stack. The 'id' argument may be
used to specify arbitrary item(s) to remove from the specified
stack.
So in your case you might do:
library(rgl)
ii <- shade3d(translate3d(cube3d(), 1, 1, 1), col="blue", alpha = 1)
shade3d(translate3d(cube3d(), 1, 1, 1), col="white", alpha = 0.5)
rgl.pop(id = ii)
I've got a list of three dimensional points, ordered by time. Is there a way to plot the points so that I can get a visual representation that also includes information on where in the list the point occurred? My initial thought is to find a way to color the points by the order in which they were plotted.
ListPlot3D drapes a sheet over the points, with no regard to the order which they were plotted.
ListPointPlot just shows the points, but gives no indication as to the order in which they were plotted. It's here that I am thinking of coloring the points according to the order in which they appear in the list.
ListLinePlot doesn't seem to have a 3D cousin, unlike a lot of the other plotting functions.
You could also do something like
lst = RandomReal[{0, 3}, {20, 3}];
Graphics3D[{Thickness[0.005],
Line[lst,
VertexColors ->
Table[ColorData["BlueGreenYellow"][i], {i,
Rescale[Range[Length[lst]]]}]]}]
As you did not provide examples, I made up some by creating a 3d self-avoiding random walk:
Clear[saRW3d]
saRW3d[steps_]:=
Module[{visited},
visited[_]=False;
NestList[
(Function[{randMove},
If[
visited[#+randMove]==False,
visited[#+randMove]=True;
#+randMove,
#
]
][RandomChoice[{{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}}]])&,
{0,0,0},
steps
]//DeleteDuplicates
]
(this is sort of buggy but does the job; it produces a random walk in 3d which avoids itself, ie, avoids revisiting the same place in subsequent steps).
Then we produce 100000 steps like this
dat = saRW3d[100000];
this is like I understood your data points to be. We then make these change color depepnding on which step it is:
datpairs = Partition[dat, 2, 1];
len = Length#datpairs;
dressPoints[pts_, lspec_] := {RGBColor[(N#First#lspec)/len, 0, 0],
Line#pts};
datplt = MapIndexed[dressPoints, datpairs];
This can also be done all at once like the other answers
datplt=MapIndexed[
{RGBColor[(N#First##2)/Length#dat, 0, 0], Line##1} &,
Partition[dat, 2, 1]
]
but I tend to avoid this sort of constructions because I find them harder to read and modify.
Finally plot the result:
Graphics3D[datplt]
The path gets redder as time advances.
If this is the sort of thing you're after, I can elaborate.
EDIT: There might well be easier ways to do this...
EDIT2: Show a large set of points to demonstrate that this is very useful to see the qualitative trend in time in cases where arrows won't scale easily.
EDIT3: Added the one-liner version.
I think Heike's method is best, but she made it overly complex, IMHO. I would use:
Graphics3D[{
Thickness[0.005],
Line[lst,
VertexColors ->
ColorData["SolarColors"] /# Rescale#Range#Length#lst ]
}]
(acl's data)
Graphics3D#(Arrow /# Partition[RandomInteger[{0, 10}, {10, 3}], 2, 1])
As to your last question: If you want to have a kind of ListLinePlot3D instead of a ListPointPlot you could simply do the following:
pointList =
Table[{t, Sin[t] + 5 Sin[t/10], Cos[t] + 5 Cos[t/10],
t + Cos[t/10]}, {t, 0, 100, .5}];
ListPointPlot3D[pointList[[All, {2, 3, 4}]]] /. Point -> Line
Of course, in this way you can't set line properties so you have to change the rule a bit if you want that:
ListPointPlot3D[pointList[[All, {2, 3, 4}]]] /.
Point[a___] :> {Red, Thickness[0.02], Line[a]}
or with
ListPointPlot3D[pointList[[All, {2, 3, 4}]]] /.
Point[a___] :> {Red, Thickness[0.002], Line[a], Black, Point[a]}
But then, why don't you use just Graphics3D and a few graphics primitives?