Scilab plot with many lines: automatic cycling trough 'LineSpec' styles - plot

I am plotting around 10 Lines in the same plot and use the built-in option of plot to cycle through colors. Sadly, this option only has 7 colors and then starts with the first color again. Is there an option like in Matlab to get a different line type, when the colors cycled through once?
I know I can change the color and line style manually for every line, but I would prefer an automatic solution.

I do not know a built-in way to do this, but reading the Linespec man page, you could create a function to cycle trough all specifiers.
The simplest of them being :
function Linespec=CycleSpec(n)
// n : from 0 to N
Linestyle =['-';'--';':';'-.']
Linecolor = ['r';'g';'b';'c';'m';'y';'k';'w']
Linemarker =['';'+';'o';'*';'.';'x';'s';'d';'^';'v';'>';'<';'p']
i = modulo(n,size(Linecolor,'*'))+1
j = modulo(floor(n/size(Linecolor,'*')),size(Linestyle,'*'))+1
k = modulo(floor(n/size(Linecolor,'*')/size(Linestyle,'*')),size(Linemarker,'*'))+1
Linespec = Linestyle(j)+Linecolor(i)+Linemarker(k)
endfunction
Which could be use as
figure(1)
for n=0:40
plot(x,x+n,CycleSpec(n))
end
And if you really want something simple, we can add a global variable storing the counter so you only need to call the function, no need for parameter
function Linespec=CycleSpec()
// n : from 0 to N
global CycleSpecCounter
if CycleSpecCounter==[] then
CycleSpecCounter = 0
end
n=CycleSpecCounter
[...] same code as before [...]
CycleSpecCounter=CycleSpecCounter+1
endfunction
and you'd only need to type
plot(x,x+n,CycleSpec())

Related

Vectors plot of electric field

I trying to plot vectors of electric field in scilab. But it always error :
champ: Wrong size for input arguments: Incompatible sizes.
the code:
epsilon0=1e-9/(36*%pi);
q=3e-9;
p=[-1,0,0];
x=-2:0.2:2;
y=-2:0.2:2;
[px,py]=meshgrid(x,y);
for m=1:length(x),
for n=1:length(y),
xp=px(m,n);
yp=py(m,n);
vektorr1x=xp-p(1);
vektorr1y=yp-p(3);
r1=sqrt(vektorr1x^2+vektorr1z^2);
if r1~=0 then
ar1x=vektorr1x/r1;
ar1y=vektorr1y/r1;
E1x=q*ar1x/(4*%pi*epsilon0*r1^2);
E1y=q*ar1y/(4*%pi*epsilon0*r1^2);
else
E1x=0;
E1y=0;
end,
end,
end,
pl=champ(px,py,E1x,E1y,[-2,-1,2,-1]);
You don't have to use loops, the following script does what you want:
epsilon0=1e-9/(36*%pi);
q=3e-9;
p=[-1,0,0];
x=-2:0.2:2;
y=-2:0.2:2;
[px,py]=ndgrid(x,y);
vektorr1x=px-p(1);
vektorr1y=py-p(3);
r1=sqrt(vektorr1x.^2+vektorr1y.^2);
ar1x=vektorr1x./r1;
ar1y=vektorr1y./r1;
E1x=q*ar1x./(4*%pi*epsilon0*r1.^2);
E1y=q*ar1y./(4*%pi*epsilon0*r1.^2);
E1x(r1==0)=0;
E1y(r1==0)=0;
clf
champ(x,y,E1x,E1y,[-2,-1,2,-1]);
To plot fields don't use meshgrid to sample the domain use ngrid instead. Moreover, don't forget to use dot-prefixed operators.

Using a function to change a variable in R

I am trying to change a variable in a function but even tho the function is producing the right values, when I go to use them in the next sections, R is still using the initial values.
I created a function to update my variables NetN and NetC:
Reproduction=function(NetN,NetC,cnrep=20){
if(NetC/NetN<=cnrep) {
DeltaC=NetC*p;
DeltaN=DeltaC/cnrep;
Crep=Crep+DeltaC;
Nrep=Nrep+DeltaN;
Brep=(Nrep*14+Crep*12)*2/1e6;
NetN=NetN-DeltaN; #/* Update N, C values */
NetC=NetC*(1-p)
print ("'Using C to allocate'")
}
else {
print("Using N to allocate");
DeltaN=NetN*p;
DeltaC=DeltaN*cnrep;
Nrep=Nrep+DeltaN;
Crep=Crep+DeltaC;
Brep=(Nrep*14+Crep*12)*2/1e6;
NetN=NetN*(1-p);
NetC=NetC-DeltaC;
} } return(c(NetC=NetC,NetN=NetN,NewB=NewB,Crep=Crep,Nrep=Nrep,Brep=Brep))}
When I use my function by say doing:
Reproduction(NetN=1.07149,NetC=0.0922349,cnrep=20)
I get the desired result printed out which includes:
NetC=7.378792e-02
However, when I go to use NetC in the next section of my code, R is still using NetC=0.0922349.
Can I make R update NetC without having to define a new variable?
In R, in general, functions shouldn't change things outside of the function. It's possible to do so using <<- or assign(), but this generally makes your function inflexible and very surprising.
Instead, functions should return values (which yours does nicely), and if you want to keep those values, you explicitly use <- or = to assign them to objects outside of the function. They way your function is built now, you can do that like this:
updates = Reproduction(NetN = 1.07149, NetC = 0.0922349, cnrep = 20)
NetC = updates["NetC"]
This way, you (a) still have all the other results of the function stored in updates, (b) if you wanted to run Reproduction() with a different set of inputs and compare the results, you can do that. (If NetC updated automatically, you could never see two different values), (c) You can potentially change variable names and still use the same function, (d) You can run the function to experiment/see what happens without saving/updating the values.
If you generally want to keep NetN, NetC, and cnrep in sync, I would recommend keeping them together in a named vector or list, and rewriting your function to take that list as input and return that list as output. Something like this:
params = list(NetN = 1.07149, NetC = 0.0922349, cnrep = 20)
Reproduction=function(param_list){
NetN = param_list$NetN
NetC = param_list$NetC
cnrep = param_list$cnrep
if(NetC/NetN <= cnrep) {
DeltaC=NetC*p;
DeltaN=DeltaC/cnrep;
Crep=Crep+DeltaC;
Nrep=Nrep+DeltaN;
Brep=(Nrep*14+Crep*12)*2/1e6;
NetN=NetN-DeltaN; #/* Update N, C values */
NetC=NetC*(1-p)
print ("'Using C to allocate'")
}
else {
print("Using N to allocate");
DeltaN=NetN*p;
DeltaC=DeltaN*cnrep;
Nrep=Nrep+DeltaN;
Crep=Crep+DeltaC;
Brep=(Nrep*14+Crep*12)*2/1e6;
NetN=NetN*(1-p);
NetC=NetC-DeltaC;
}
## Removed extra } and ) ??
return(list(NetC=NetC, NetN=NetN, NewB=NewB, Crep=Crep, Nrep=Nrep, Brep=Brep))
}
This way, you can use the single line params <- Reproduction(params) to update everything in your list. You can access individual items in the list with either params$Netc or params[["NetC"]].

Filter vertices on several properties - Julia

I am working on julia with the Metagraphs.jl library.
In order to conduct an optimization problem, I would like to get the set/list of edges in the graph that point to a special set of vertices having 2 particular properties in common.
My first guess was to first get the set/list of vertices. But I am facing a first issue which is that the filter_vertices function doesn't seem to accept to apply a filter on more than one property.
Here is below an example of what I would like to do:
g = DiGraph(5)
mg = MetaDiGraph(g, 1.0)
add_vertex!(mg)
add_edge!(mg,1,2)
add_edge!(mg,1,3)
add_edge!(mg,1,4)
add_edge!(mg,2,5)
add_edge!(mg,3,5)
add_edge!(mg,5,6)
add_edge!(mg,4,6)
set_props!(mg,3,Dict(:prop1=>1,:prop2=>2))
set_props!(mg,1,Dict(:prop1=>1,:prop2=>0))
set_props!(mg,2,Dict(:prop1=>1,:prop2=>0))
set_props!(mg,4,Dict(:prop1=>0,:prop2=>2))
set_props!(mg,5,Dict(:prop1=>0,:prop2=>2))
set_props!(mg,6,Dict(:prop1=>0,:prop2=>0))
col=collect(filter_vertices(mg,:prop1,1,:prop2,2))
And I want col to find vertex 3 and no others.
But the filter_vertices would only admit one property at a time and then it makes it more costly to do a loop with 2 filters and then try to compare in order to sort a list with the vertices that have both properties.
Considering the size of my graph I would like to avoid defining this set with multiple and costly loops. Would any one of you have an idea of how to solve this issue in an easy and soft way?
I ended up making this to answer my own question:
fil3=Array{Int64,1}()
fil1=filter_vertices(mg,:prop1,1)
for f in fil1
if get_prop(mg,f,:prop2)==2
push!(fil3,f)
end
end
println(fil3)
But tell me if you get anything more interesting
Thanks for your help!
Please provide a minimal working example in a way we can simply copy and paste, and start right away. Please also indicate where the problem occurs in the code. Below is an example for your scenario:
Pkg.add("MetaGraphs")
using LightGraphs, MetaGraphs
g = DiGraph(5)
mg = MetaDiGraph(g, 1.0)
add_vertex!(mg)
add_edge!(mg,1,2)
add_edge!(mg,1,3)
add_edge!(mg,1,4)
add_edge!(mg,2,5)
add_edge!(mg,3,5)
add_edge!(mg,5,6)
add_edge!(mg,4,6)
set_props!(mg,3,Dict(:prop1=>1,:prop2=>2))
set_props!(mg,1,Dict(:prop1=>1,:prop2=>0))
set_props!(mg,2,Dict(:prop1=>1,:prop2=>0))
set_props!(mg,4,Dict(:prop1=>0,:prop2=>2))
set_props!(mg,5,Dict(:prop1=>0,:prop2=>2))
set_props!(mg,6,Dict(:prop1=>0,:prop2=>0))
function my_vertex_filter(g::AbstractMetaGraph, v::Integer, prop1, prop2)
return has_prop(g, v, :prop1) && get_prop(g, v, :prop1) == prop1 &&
has_prop(g, v, :prop2) && get_prop(g, v, :prop2) == prop2
end
prop1 = 1
prop2 = 2
col = collect(filter_vertices(mg, (g,v)->my_vertex_filter(g,v,prop1,prop2)))
# returns Int[3]
Please check ?filter_vertices --- it gives you a hint on what/how to write to define your custom filter.
EDIT. For filtering the edges, you can have a look at ?filter_edges to see what you need to achieve the edge filtering. Append the below code excerpt to the solution above to get your results:
function my_edge_filter(g, e, prop1, prop2)
v = dst(e) # get the edge's destination vertex
return my_vertex_filter(g, v, prop1, prop2)
end
myedges = collect(filter_edges(mg, (g,e)->my_edge_filter(g,e,prop1,prop2)))
# returns [Edge 1 => 3]
I found this solution:
function filter_function1(g,prop1,prop2)
fil1=filter_vertices(g,:prop1,prop1)
fil2=filter_vertices(g,:prop2,prop2)
filter=intersect(fil1,fil2)
return filter
end
This seems to work and is quite easy to implement.
Just I don't know if the filter_vertices function is taking a lot of computational power.
Otherwise a simple loop like this seems to also work:
function filter_function2(g,prop1,prop2)
filter=Set{Int64}()
fil1=filter_vertices(g,:prop1,prop1)
for f in fil1
if get_prop(g,f,:prop2)==prop2
push!(filter,f)
end
end
return filter
end
I am open to any other answers if you have some more elegant ones.

Function keeps repeating in Octave

My code is written in a file "plot.m".
If I put the following code in "plot.m", when I call plot("20%"), the Octave GUI will keep opening a new window with a new figure indefinitely.
function X = plot(folderName)
X = 0;
data = ([folderName, "\\summary.txt"]);
NUM_SURVIVED = data(1);
NUM_DATA = size(data)(1)-1;
FINAL_WEALTH = data(2 : NUM_DATA);
%plot FINAL_WEALTH
figure;
plot(1:numel(FINAL_WEALTH), FINAL_WEALTH, '-b', 'LineWidth', 2);
xlabel('x');
ylabel('FINAL_WEALTH');
end
However, if I put the following code in "plot.m" and run it, the program works as intended and will plot data from "summary.txt".
data = ("20%\\summary.txt");
NUM_SURVIVED = data(1);
NUM_DATA = size(data)(1)-1;
FINAL_WEALTH = data(2 : NUM_DATA);
%plot FINAL_WEALTH
figure;
plot(1:numel(FINAL_WEALTH), FINAL_WEALTH, '-b', 'LineWidth', 2);
xlabel('x');
ylabel('FINAL_WEALTH');
Any idea what I am doing wrong in the first section of code? I would like to write it as a function so that I can call it multiple times for different folder names.
When you call plot from the function plot, you get endless recursion. Rename your function and its file.
Just adding to Michael's answer, if you really wanted to name your function as "plot" and override the built-in plot function, but still wanted to be able to call the built-in plot function inside it, this is actually possible to do by using the builtin function to call the built-in version of plot. Your code would then look like this:
function X = plot (folderName)
% same code as before
figure;
builtin ("plot", 1:numel(FINAL_WEALTH), FINAL_WEALTH, '-b', 'LineWidth', 2);
xlabel ('x');
ylabel ('FINAL_WEALTH');
end
Obviously, whether it's a good idea to overload such a core function in the first place is an entirely different discussion topic. (Hint: don't!)

sunburst.R total frequency count is incorrect

I am plotting a sunburst donut and I cannot figure out why the total is incorrect.
library(sunburstR)
reports <- data.frame(
sequence = c("SVP-VP-Dir-end","SVP-VP-Dir-end","SVP-VP-Dir-end","SVP-VP-Dir-end","SVP-No VP-Dir-end","SVP-No VP-Dir-end","SVP-No VP-Dir-end"),
freq = as.numeric(c("167","60","51","32","5","1","1")))
sunburst(reports, count = TRUE)
It is supposed to be 100% 317 of 317 . Anyone know how to fix this? There is not much documentation on this great package.
Also, I would like it to have a default value in the center of donut.
If there is another way to create an interactive donut using R, please let me know.
Thanks you in advance.
It looks like the default function generating the message in the center of the donut rounds the total value to the nearest ten.
But you can customize this function using the explanation argument of sunburst. Oddly, the customized function (in javascript) must be provided as a string.
Try the following function:
custom.message = "function (d) {
root = d;
while (root.parent) {
root = root.parent
}
p = (100*d.value/root.value).toPrecision(3);
msg = p+' %<br/>'+d.value+' of '+root.value;
return msg;
}"
Now:
sunburst(reports, explanation = custom.message )
will generate the donut displaying exact total values. The count argument is no longer needed, as it is used by the default explanation function.
The value returned by custom.message is html code. As you can see, I've just inserted a line break (<br/>). You can modify the msg return value to further customize the look and feel.

Resources