Converting matlab-style indexing to numpy - matlab

I would like to convert (a more complicated form of) the follwing Matlab code
a=zeros(9,9);
a(3+(1:3),6+(1:3))=1;
to Numpy. I tried
from numpy import zeros, r_
a=zeros((9,9))
a[3+r_[0:3],6+r_[0:3]] = 1
But this only puts 3 1's in the matrix. How can I write the matlab code in a similar (short) form in Python?

To be honest, I'd probably just do
>>> a = zeros((9,9))
>>> a[3:6, 6:9] = 1
or the non-hardcoded equivalent. If you want the indexing to look more like Matlab's here, though, then you can use ix_:
>>> a = zeros((9,9))
>>> a[ix_(3+r_[0:3], 6+r_[0:3])] = 1
>>> a
array([[ 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., 1., 1., 1.],
[ 0., 0., 0., 0., 0., 0., 1., 1., 1.],
[ 0., 0., 0., 0., 0., 0., 1., 1., 1.],
[ 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.]])

Related

How to fit a curve to a set of data for same x values?

I have some curves from the lab tests on material. each set of data has different lenghts. i am willing to fit a curve to these data.
Lets start with data having same lenght: y1 y2 y3 with same x values.
import numpy as np
import matplotlib.pyplot as plt
def my_function(x,y):
curve = np.polyfit(x, y, 4)
poly = np.poly1d(curve)
new_x = np.arange(x[0],x[-1],1)
new_y= poly(new_x)
plt.plot(new_x, new_y)
plt.scatter(x, y)
print(poly)
x = [0, 5.25, 10.5, 21, 31.5, 42, 52.5, 63, 73.5, 84, 94.5, 99.75, 105]
y1=[0.2535,0.3552,0.456,0.489,0.5265,0.58384,1.87616,2.87328,2.55184,2.66992,2.8208,3.09632,3.51616]
y2=[0.116112,0.425088,0.582528,0.70192,1.07584,2.41408,3.75232,4.61824,2.55184,2.66992,2.8208,3.09632,3.51616]
y3=[0.389664,1.166368,1.60392,2.05984,2.788,4.02784,5.0184,5.60224,2.55184,2.66992,2.8208,3.09632,3.51616]
ylist = [ y1, y2, y3]
for y in ylist:
my_function(x,y)
My final goal is to do this for pairs of y and x, which their lenghts are different from other pairs of data.
what im expecting is like this:
enter image description here
I may be misunderstanding your question but nothing in your code presumes that all your y's have to have the same length. This works for me:
import numpy as np
import matplotlib.pyplot as plt
def my_function(x,y):
curve = np.polyfit(x, y, 4)
poly = np.poly1d(curve)
new_x = np.arange(x[0],x[-1],1)
new_y= poly(new_x)
plt.plot(new_x, new_y)
plt.scatter(x, y)
print(poly)
x1 = [0, 5.25, 10.5, 21, 31.5, 42, 52.5, 63, 73.5, 84, 94.5, 99.75, 105]
x2 = [0, 5.25, 10.5, 21, 31.5, 42, 52.5, 63, 73.5, 84, 94.5, 99.75]
x3 = [0, 5.25, 10.5, 21, 31.5, 42, 52.5, 63, 73.5, 84, 94.5]
y1=[0.2535,0.3552,0.456,0.489,0.5265,0.58384,1.87616,2.87328,2.55184,2.66992,2.8208,3.09632,3.51616]
y2=[0.116112,0.425088,0.582528,0.70192,1.07584,2.41408,3.75232,4.61824,2.55184,2.66992,2.8208,3.09632]
y3=[0.389664,1.166368,1.60392,2.05984,2.788,4.02784,5.0184,5.60224,2.55184,2.66992,2.8208]
ylist = [ y1, y2, y3]
xlist = [ x1, x2, x3]
for x, y in zip(xlist, ylist):
my_function(x,y)
Edit: From the clarification in the comment
the goal is to fit one curve for all three y1 y2 y3 with their corresponding x1 x2 x3 curves
So all points in the curves defined by (x1, y1), (x2, y2), (x3, y3), ... should be fit to a single polynomial.
This can be done by simply concatenating the vectors containing the data:
x_tot = np.concatenate((x1, x2, x3))
y_tot = np.concatenate((y1, y2, y3))
my_function(x_tot,y_tot)
Which results in:
Note that the (x, y) arrays don't have to be the same length. In case that y1, y2, ..., share the same x, the concatenation should be x_tot = np.concatenate((x, x, x))

NetworkX visualization from Torch Geometric, duplicated unconnected nodes

I have nodes features stored in a dataframe and graphs attributes stored in an object, and I am trying to visualize the Torch Geometric graphs via networkx, but beside the actual nodes it also plots an equal number of unconnected nodes, and I am trying to understand why..
for example for graph 8779, if I construct the networkx graph from my object it looks fine:
G = nx.Graph()
for e in graphs[8779].edges:
G.add_edge(e.source, e.target)
plt.figure(8779)
plt.suptitle(8779)
nx.draw(G)
When I go through Torch Geometric it doesn't:
attr = []
for n in graphs[8779].nodes:
vals = df_features[df_features.event_id == int(n.event_id)].iloc[:,1:].values[0]
attr.append(vals)
attr = torch.FloatTensor(np.array(attr))
rows = [int(e.source) for e in graphs[8779].edges]
cols = [int(e.target) for e in graphs[8779].edges]
edges = torch.tensor([rows, cols])
gr = data.Data(x=attr, edge_index=edges)
vis = to_networkx(gr)
plt.figure(1,figsize=(15,13))
nx.draw(vis, cmap=plt.get_cmap('Set3'),node_size=70,linewidths=6)
plt.show()
I checked the Torch Geometric graph properties and everything looks fine:
('x', tensor([[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., 1., 0.],
[0., 0., 0., ..., 0., 1., 0.]]))
('edge_index', tensor([[829072, 829072, 829068, 829118, 829132, 829070, 829073, 829066, 829113,
829084, 829075, 829075, 829129, 829090, 829082],
[829073, 829075, 829070, 829129, 829133, 829072, 829075, 829068, 829118,
829132, 829082, 829084, 829132, 829113, 829090]]))
('num_nodes', 14)
what am I doing wrong? :(

Matlab extends graph in EPS export beyond limits

I encountered strange behavior from Matlab when using the eps export. When I set up a figure like this:
subplot(2,1,1)
x = [duration([-3, 0, 0]), duration([-2, 0, 0]), duration([-1, 0, 0]), duration([0, 59, 59]), duration([1, 0, 0]), duration([2, 0, 0]), duration([3, 0, 0]), duration([3, 0, 1]), duration([5, 0, 0])];
y = [0, 0, 0, 0, 1, 1, 1, 0, 0];
plot(x,y)
set(gca,'XLim',[0 operationEnd-operationStart]);
xtickformat('hh:mm');
box off
subplot(2,1,2)
yyaxis left
plot(x,y)
yyaxis right
plot(x,y,'--');
set(gca,'XLim',[0 operationEnd-operationStart]);
xtickformat('hh:mm');
saveas(f,[PATH_SAVE,'eps_export_issue'],'eps2c');
The resulting figure looks in Matlab like this:
However when I open the exported EPS in Inkscape it seems to ignore the set XLim if the figure and it looks like this:
The issue also occurs if I don't use subplot and don't use duration as this snippet:
x = [-3, -2, -1, 0.99, 1, 2, 3, 3.01, 5];
y = [0, 0, 0, 0, 1, 1, 1, 0, 0];
f = figure();
yyaxis left
plot(x,y)
yyaxis right
plot(x,y,'--');
set(gca,'XLim',[0 4]);
box off
saveas(f,'eps_export_float','eps2c');
leads to an exported EPS that looks like this with the same issue:
How can I resolve this?

Matlab: how to remove extra y axis generated by 'axes'?

I am now having trouble plotting something by matlab.
x1 = 1:2500;
y1 = 1:2500:2500^2;
y2 = 1:2400:2500*2400;
figure
subplot(2,2,1);
semilogy(x1, y1, '-', x1, y2, '-.');
set(gca,'xticklabel',{[]});
pp = subplot(2,2,2);
pospp = get(pp, 'Position');
ax3 = axes('Position',pospp);
ax4 = axes('Position',[0.7 0.7 0.1 0.1]);
axes(ax3);
semilogy(x1, y1, '-', x1, y2, '-.');
set(gca,'xticklabel',{[]});
axes(ax4);
semilogy(2000:2500, y1(2000:2500), '-', 2000:2500, y2(2000:2500), '-.');
set(ax3,'xticklabel',{[]});
set(ax4,'xticklabel',{[]});
Here is the figure
I am wondering how can I remove one y axis from the right subplot? The one with "0, 0.2, 0.4, 0.6, 0.8, 1.0"? I only want to keep the log-scale one.
Thank you.
In this line:
ax3 = axes('Position',pospp);
you create an extra axes object. Remove this line and the axes will be gone. Use pp instead of ax3.

Drawing 3D points in Matlab and connect them in order via line

I have an array that contains 3D float points. Not only I want to depict them in a figure but also I want to connect them with lines.
Example) lets say we have array called X:
X=[0, 0, 0; 0.48, -0.88, 0.09; -1.06, 0.55, 0.9; -0.65, 1.5, -1.44; 1.1, 0.59,
-1.11;0.76, 0.86, -0.52; -1.08, -0.28, 0.55; 1.47, -1.21, 0.14; 1.42, -2.15, 0.71; -0.64,
1.87, 2.4;2.32, -2.44, 2.02; 2.25, -2.56, -3.03; 2.35, 2.65, -1.5; 0.23, -2.25, 2.78; 2.47,
-3.12, -1.91; 2.27, 1.37, -3.05; 2.3, 1.9, -1.29; -1.77, -0.51, 2.33];
X1= [0,0,0]
X2=[0.48, -0.88, 0.09]
X3=[-1.06, 0.55, 0.9] ...
now I want that X1...Xn to be drawn in figure as points then X1 get connected to X2, X2 get connected to X3, X3 get connected to X4, etc
how could I do that?
Here is what I ve done but I get a wrong figure:
figure;hold on;
P=[];
for i=1:size(X,1)
x=X(i,1);
y=X(i,2);
z=X(i,3);
A=[ x,y,z];
P=vertcat(P,A);
plot(P);
end
And Here is the output:
Check out the plot3 documentation.
In particular, plot3(X, Y, Z) will plot the points and join them with a line.
In your case:
plot3(X(:, 1), X(:, 2), X(:, 3))