I want to produce a plot with two y-axis and apply multiple datasets to one of the axis. For example
[hAx,hLine1,hLine2] = plotyy([x1',x2',x3'],[y1',y2',y3'],x4,y4);
where x1 and y1 are 1000x1-arrays, x2 and y2 are 2000x1-arrays and x3 and y3 are 3000x1-arrays. The range of the arrays is more or less the same. When i try producing this plot, MATLAB gets me an error saying
Error using horzcat Dimensions of matrices being concatenated are not
consistent.
Is there any workaround for this error?
EDIT:
Here's my real code, which is not working:
[hAx,hLine1,hLine2] = plotyy([erg_cm.Time.data,erg_cm.Time.data,t',t'],...
[erg_cm.Car_FxFL.data,erg_cm.Car_FxFR.data,Fx(1,:),Fx(2,:)],...
erg_cm.Time.data,diff);
And my original data:
erg_cm.Time.data is 1x4001
t is 80300x1
erg_cm.Car_FxFL.data is 1x4001
erg_cm.Car_FxFR.data is 1x4001
Fx is 4x80300
diff is 1x4001
Your x and y vectors are column vectors and you're trying to concatenate them horizontally, which you cannot do because they are not the same size. You want to vertically concatenate them:
[hAx,hLine1,hLine2] = plotyy([x1;x2;x3],[y1;y2;y3],x4,y4);
EDIT: This is what I'm testing with
erg_cm.Time.data = rand(1, 4001);
t = rand(80300, 1);
erg_cm.Car_FxFL.data = rand(1, 4001);
erg_cm.Car_FxFR.data = rand(1, 4001);
Fx = rand(4, 80300);
diff = rand(1, 4001);
[hAx,hLine1,hLine2] = plotyy([erg_cm.Time.data,erg_cm.Time.data,t',t'],...
[erg_cm.Car_FxFL.data,erg_cm.Car_FxFR.data,Fx(1,:),Fx(2,:)],...
erg_cm.Time.data,diff);
Related
So I tried to plot a contour in Julia by interpolating a 2D function, using the following code:
using Interpolations
using Plots
gr()
xs = 1:0.5:5
ys = 1:0.5:8
# The function to be plotted
f(x, y) = (3x + y ^ 2)
g = Float64[f(x,y) for x in xs, y in ys]
# Interpolate the function
g_int = interpolate(g, BSpline(Quadratic(Line(OnCell()))))
# Scale the interpolated function to the correct grid
gs_int = scale(g_int, xs, ys)
xc = 1:0.1:5
yc = 1:0.1:5
# Compare the real value and the interpolated value of the function at an arbitrary point
println("gs_int(3.2, 3.2) = ", gs_int(3.2, 3.2))
println("f(3.2, 3.2) = ", f(3.2, 3.2))
# Contour of the interpolated plot
p1 = contour(xs, ys, gs_int(xs, ys), fill=true)
# Real contour of the function
p2 = contour(xc, yc, f, fill=true)
plot(p1, p2)
And this obviously didn't give the correct contour, although the interpolation was seemingly correct:
The problem was fixed by transposing gs_int(xs, ys):
p1 = contour(xs, ys, gs_int(xs, ys)', fill=true)
Then I randomly generated some points in 2D space, and repeated the same procedures:
using DelimitedFiles
using Interpolations
using Plots
gr()
data = readdlm("./random_points.txt", Float64)
# Create a dictionary to test different orders of interpolations.
inter = Dict("constant" => BSpline(Constant()),
"linear" => BSpline(Linear()),
"quadratic" => BSpline(Quadratic(Line(OnCell()))),
"cubic" => BSpline(Cubic(Line(OnCell())))
)
x = range(-10, length=64, stop=10)
y = range(-10, length=64, stop=10)
v_unscaled = interpolate(data, inter["cubic"])
v = scale(v_unscaled, x, y)
# The contour of the data points
p0 = contour(x, y, data, fill=true)
display(p0)
# The contour of the interpolated function
p_int = contour(x, y, v(x,y)', fill=true)
display(p_int)
However the two contour plots don't look the same.
As I removed the apostrophe after v(x,y), this worked:
p_int = contour(x, y, v(x,y), fill=true)
Now I don't get it. When should I apply transposition, and when shouldn't I do so?
That's because in your first example you plot a function, in the second example you plot two arrays. The two arrays don't need to be transposed as they are oriented the same way. But in the first example, the way you generate the array is transposed relative to the way Plots generates an array from the 2-d function you're passing.
When you plot a function, Plots will calculate the outcome as g = Float64[f(x,y) for y in ys, x in xs] not the other way around, like you did in your code. For a good discussion of transposes in plotting, again refer to https://github.com/JuliaPlots/Makie.jl/issues/205
Interleaver: Assume we have vector X= randi(1,N) I would like to split the contents of X into two new vectors X1and X2 such that the first element of X is the first element of X1, the first element of X2 is the second element of X, the third element of X is the second element of X1 and the fourth element of X is the second element of X2... etc till the last element of the vector `X.
I have the following idea
X1(1)=X(1);
X2(1)=X(2);
for i=1:length(X)
X1(i)= X(i+2);
end
for j=2:length (X)
X2(i)= X(i+2)
end
My question is: is my method correct? is there a better way to do it?
Deinterleaver
I also have the reverse problem so basically in this case I have X1 and X2 and would like to recover X, how would I efficiently recover X?
I think the terminology in this question is reversed. Interleaving would be to merge two vectors alternating their values:
x1 = 10:10:100;
x2 = 1:1:10;
x = [x1;x2];
x = x(:).';
This is the same as the one-liner:
x = reshape([x1;x2],[],1).';
Deinterleaving would be to separate the interleaved data, as already suggested by David in a comment and Tom in an answer:
y1 = x(1:2:end);
y2 = x(2:2:end);
but can also be done in many other ways, for example inverting the process we followed above:
y = reshape(x,2,[]);
y1 = y(1,:);
y2 = y(2,:);
To verify:
isequal(x1,y1)
isequal(x2,y2)
I was hoping, as well for some cool new one liner, but anyway, following the previous answer you can use the same indexing expression for the assignment.
x = 1:20
x1 = x(1:2:end)
x2 = x(2:2:end)
y = zeros(20,1)
y(1:2:end) = x1
y(2:2:end) = x2
I think it's hard to get a cleaner solution than this:
x = 1:20
x1 = x(1:2:end)
x2 = x(2:2:end)
Just to add another option, you could use the deal function and some precomputed indices. This is basically the same as the answer from Peter M, but collecting the assignments into single lines:
X = randi(10, [1 20]); % Sample data
ind1 = 1:2:numel(X); % Indices for x1
ind2 = 2:2:numel(X); % Indices for x2
[x1, x2] = deal(X(ind1), X(ind2)); % Unweave (i.e. deinterleave)
[X(ind1), X(ind2)] = deal(x1, x2); % Interleave
I've been trying to extend the xor-swap to more than two variables, say n variables. But I've gotten nowhere that's better than 3*(n-1).
For two integer variables x1 and x2 you can swap them like this:
swap(x1,x2) {
x1 = x1 ^ x2;
x2 = x1 ^ x2;
x1 = x1 ^ x2;
}
So, assume you have x1 ... xn with values v1 ... vn. Clearly you can "rotate" the values by successively applying swap:
swap(x1,x2);
swap(x2,x3);
swap(x3,x4);
...
swap(xm,xn); // with m = n-1
You will end up with x1 = v2, x2 = v3, ..., xn = v1.
Which costs n-1 swaps, each costing 3 xors, leaving us with (n-1)*3 xors.
Is a faster algorithm using xor and assignment only and no additional variables known?
As a partial result I tried a brute force search for N=3,4,5 and all of these agree with your formula.
Python code:
from collections import *
D=defaultdict(int) # Map from tuple of bitmasks to number of steps to get there
N=5
Q=deque()
Q.append( (tuple(1<<n for n in range(N)), 0) )
goal = (tuple(1<<( (n+1)%N ) for n in range(N)))
while Q:
masks,ops = Q.popleft()
if len(D)%10000==0:
print len(D),len(Q),ops
ops += 1
# Choose two to swap
for a in range(N):
for b in range(N):
if a==b:
continue
masks2 = list(masks)
masks2[a] = masks2[a]^masks2[b]
masks2 = tuple(masks2)
if masks2 in D:
continue
D[masks2] = ops
if masks2==goal:
print 'found goal in ',ops
raise ValueError
Q.append( (masks2,ops) )
I'm attempting to draw streamlines for a two-dimensional vector field. I have the data in a two-dimensional array with one column each containing the X coordinate, y-coordinate, horizontal velocity, and vertical velocity. I'm attempting to use the streamline function but I'm having trouble figuring out how to format the input data correctly.
I know that each input matrix should be the same size. So I have attempted to use the following to get workable inputs:
[X Y]= meshgrid(sf(1:250:end,1), sf(1:250:end, 2));
[U V]= meshgrid(sf(1:250:end,3), sf(1:250:end,4));
But my velocity matrices obviously no longer make sense compared to my locations.
I'm at a bit of a loss so any help would be awesome.
You may use griddata to re-arrange your data into a regular grid
f = min( sf(:,1:2), [], 1 ); %// XY grid starting points
t = max( sf(:,1:2), [], 1 ); %// XY endpoints
[X Y] = meshgrid( linspace( f(1), t(1), 50 ), linspace( f(2), t(2), 50 ) ); %//grid
U = griddata( sf(:,1), sf(:,2), sf(:,3), X, Y );
V = griddata( sf(:,1), sf(:,2), sf(:,4), X, Y );
startx = ; %// define streamline starting points
starty = ; %//
streamline( X, Y, U, V, startx, starty );
I am plotting a XY graph with two different sets of X and Y values. This is how my dataset looks -> [ X1 = {1,3,5,...}, Y1 = {104, 98, 36,....} and X2 = {2,4,6..}, Y2 = { 76, 65, 110..}].
This is the code I am using:
series1.DependentValueBinding = new System.Windows.Data.Binding("Y1");
series1.IndependentValueBinding = new System.Windows.Data.Binding("X1");
series1.DependentRangeAxis = YAxis;
series1.IndependentAxis = XAxis;
series2.DependentValueBinding = new System.Windows.Data.Binding("Y2");
series2.IndependentValueBinding = new System.Windows.Data.Binding("X2");
series2.DependentRangeAxis = YAxis;
series2.IndependentAxis = XAxis;
This code works fine for assigning two series to single Y-Axis, but when two series with different X and Y values are assigned to X-Axis it messes up the first series. It plots both Y1 = {104, 98, 36,....} and Y2 = { 76, 65, 110..} with respect to X2 = {2,4,6..}, instead of plotting X1 with respect to Y1 and X2 with respect to Y2 and having only one X and Y axis.
Please advice me on what needs to be done to assign two different set of values to single X-axis.
Thank you in advance!
-Anna
Problem is solved. This code is correct.. There is something to do with my value assignment (I noticed that I was clearing X1 value before using X2. But to make the code work all the values X1, Y1, X2, Y2 should be preserved until the chart is created)..Thank you!
series1.DependentValueBinding = new System.Windows.Data.Binding("Y1");
series1.IndependentValueBinding = new System.Windows.Data.Binding("X1");
series1.DependentRangeAxis = YAxis;
series1.IndependentAxis = XAxis;
series2.DependentValueBinding = new System.Windows.Data.Binding("Y2");
series2.IndependentValueBinding = new System.Windows.Data.Binding("X2");
series2.DependentRangeAxis = YAxis;
series2.IndependentAxis = XAxis;