I was wondering if Julia has an easily already built in capability to pass arguments meant for a function in a function?
For example,
I'm working with Gadfly but I want to create a function that makes a specific plot, let's say one that does a line graph with the plots pointed already.
So for a working example
using Gadfly, Random
Random.seed!(50)
x = randn(10)
y = 10 * x .+ 2 .+ randn(10)/10
function dummy1(x, y; plotOptionsToPass...)
plot(x = x, y = y, Geom.point, Geom.line; plotOptionsToPass...)
end
And I want to be able to pass in all different types of Gadfly plot options such as
dummy1(x, y; Theme(panel_fill = nothing))
so that it makes the dummy1 function turn into something like
plot(x = x, y = y, Geom.point, Geom.line; Theme(panel_fill = nothing))
without me having to actually prespecify all of the types of options Gadfly allows plot() to take.
Not sure what you are after, but maybe it helps to see that you can define a new function inside dummy1 and return it. The retruned fucntion will use less arguments. dummy1 becomes a drawing function 'constructor'.
function dummy1(;plotOptionsToPass...)
function foo(x, y)
plot(x = x, y = y, Geom.point, Geom.line; plotOptionsToPass...)
end
return foo
end
# create new drawing function
new_artist = dummy1(Theme(panel_fill = nothing))
# draw something
new_artist(x, y)
Related
I have a function in Julia that produces a plot using the Plots package plot() command. I'd like to set some optional arguments for the plot by passing arguments into my outer function. For example, I'd like to set title and axis labels without needing to program a bunch of if statements to check what parameters I'm trying to pass in. A MWE of what I'd like to do is as follows:
function outer(data; plot_options...)
x = data.x
y = data.y
plot(x,y, plot_options...)
end
So that if I call something like outer(data, title="My Title", lw=2) I produce a plot with title set to "My Title" and a linewidth of 2. Trying the naive thing that I programmed above results in an error.
function outer(data; plot_options...)
x = data.x
y = data.y
plot(x,y; plot_options...)
end
missed a semicolon?
I'd like to plot something like this:
plot(dnorm(mean=2),from=-3,to=3)
But it doesn't work as if you do:
plot(dnorm,from=-3,to=3)
what is the problem?
The answer you received from #r2evans is excellent. You might also want to consider learning ggplot, as in the long run it will likely make your life much easier. In that case, you can use stat_function which will plot the results of an arbitrary function along a grid of the x variable. It accepts arguments to the function as a list.
library(ggplot2)
ggplot(data = data.frame(x=c(-3,3)), aes(x = x)) +
stat_function(fun = dnorm, args = list(mean = 2))
curve(dnorm(x, mean = 2), from = -3, to = 3)
The curve function looks for the xname= variable (defaults to x) in the function call, so in dnorm(x, mean=2), it is not referencing an x in the calling environment, it is a placeholder for curve to use for iterated values.
The reason plot(dnorm, ...) works as it does is because there exists graphics::plot.function, since dnorm in that case is a function. When you try plot(dnorm(mean=2)), the dnorm(mean=2) is no longer a function, it is a call ... that happens to fail because it requires x (its first argument) be provided.
Incidentally, plot.function calls curve(...), so other than being a convenience function, there is very little reason to use plot(dnorm, ...) over curve(dnorm(x), ...) other than perhaps a little code-golf. The biggest advantage to curve is that it lets you control arbitrary arguments to the dnorm() function, whereas plot.function does not.
I want to plot the function
4(x)^2 = ((y)^2/(1-y));
how can I plot this?
--> 4*(x) = ((y^2)*(1-y)^-1)^0.5;
4*(x) = ((y^2)*(1-y)^-1)^0.5;
^^
Error: syntax error, unexpected =, expecting end of file
Since Scilab 6.1.0, plotimplicit() does it:
plotimplicit "4*x^2 = y^2/(1-y)"
xgrid()
Can't do more simple. Result:
Well, you have to first create a function and for that you have to express one variable in terms of the other.
function x = f(y)
x = (((y^2)*(1-y)^-1)^0.5)/4;
endfunciton
Then you need to generate the input data (i.e, the points at which you want to evaluate the function)
ydata = linspace(1, 10)
Now you push your input point through the function to get your output points
xdata = f(ydata)
Then, you can plot the pairs of x and y using:
plot(xdata, ydata)
Or even easier, without the intermediate step of generating the output data, you can simply do:
plot(f(ydata), ydata)
BTW. I find it strange that the function you are trying to plot is x in terms of y, usually, x is the input variable, but I hope you know what you are trying to accomplish.
Reference: https://www.scilab.org/tutorials/getting-started/plotting
Take care that y must be in [-inf 1[
y=linspace(-10 ,1.00001,1000);
x = sqrt(y^2./(1-y))/4;
clf; plot(y,x),plot(y,-x)
If x is a solution -x is also solution
I have this function which I have saved in the database.
runifrect <- function(n,a,b,z,d) {
else(print("Check if the x and y coordinates lie as such: 0<=a<b<=1 and 0<=z<d<=1"))}
Now I am trying to define this function with the use of the old one:
plotrectpoints<- function(runifrect(n,a,b,z,d),a,b,z,d) {
However I am getting an error I dont understand what is wrong with the function, I want it to work for any arbitrary values n,a,b,z,d.
When a function is defined in R it cannot evaluate the values in parenthesis. It rather creates dummy objects which get the values when the function is called. These dummy object names follow the same rules that are applied to all variables names. Since you cannot have a variable name contained parenthesis, you cannot include it into the list of arguments when you define the function.
First function definition
runifrect <- function(n,a,b,z,d) {
if(a<1&a>=0&b>0&b<=1&z<1&z>=0&d<=1&d>0) {
x <- runif(n,a,b)
y <- runif(n,z,d)
k<-c(x,y)
matrix(k,nrow = n,ncol = 2)}
else(print("Check if the x and y coordinates lie as such: 0<=a<b<=1 and 0<=z<d<=1"))}
Second function definition
plotrectpoints<- function(x,a,b,z,d) {
plot(x,
xlim=c(0,1),
ylim=c(0,1),
main = "Plot of rectangle and randomly generated points")
rect(a,z,b,d, border='red',lty='dotted')}
Call to the function
plotrectpoints( runifrect(n,a,b,z,d), a,b,z,d)
This is my first answer on this platform. Please bear with me.
If your end goal is to call the 'runifrect()' function from the 'plotrectpoints()' function, we can remove the 'runifrect(n,a,b,z,d)' parameter and replace that with 'n'.
The code should look as follows:
runifrect <- function(n,a,b,z,d) {
if(a<1&a>=0&b>0&b<=1&z<1&z>=0&d<=1&d>0) {
x <- runif(n,a,b)
y <- runif(n,z,d)
k<-c(x,y)
matrix(k,nrow = n,ncol = 2)}
else(print("Check if the x and y coordinates lie as such: 0<=a<b<=1 and 0<=z<d<=1"))}
plotrectpoints<- function(n,a,b,z,d) {
plot(runifrect(n,a,b,z,d),
xlim=c(0,1),
ylim=c(0,1),
main = "Plot of rectangle and randomly generated points")
rect(a,z,b,d, border='red',lty='dotted')}
and I have used the following parameters to test.
plotrectpoints(10,0.5,0.8,0.3,0.7)
I have also attached the plot the above code generated.
enter image description herePlease let me know if the above code is what you are looking for.
Using the Plots.jl package in Julia, I am able to use various backends to make a scatter plot based on two vectors x and y
k = 100
x = rand(k)
y = rand(k)
scatter(x, y)
I am unable to find information about how to color them according to some length k vector z. How do you do that?
The following method will be much better than jverzani's (you don't want to create a new series for every data point). Plots could use some additional love for manually defining color vectors, but right now gradients are pretty well supported, so you can take advantage of that.
using Plots
pyplot(size=(400,200), legend=false) # set backend and set some session defaults
scatter(rand(30),
m = ColorGradient([:red, :green, :blue]), # colors are defined by a gradient
zcolor = repeat( [0,0.5,1], 10) # sample from the gradient, cycling through: 0, 0.5, 1
)
I would have thought if you defined k as a vector of color symbols this would work: scatter(x, y, markercolors=k), but it doesn't seem to. However, adding them one at a time will, as this example shows:
using Plots
xs = rand(10)
ys = rand(10)
ks = randbool(10) + 1 # 1 or 2
mcols = [:red, :blue] # together, mcols[ks] is the `k` in the question
p = scatter(xs[ks .== 1], ys[ks .== 1], markercolor=mcols[1])
for k = 2:length(mcols)
scatter!(xs[ks .== k], ys[ks .== k], markercolor=mcols[k])
end
p
If the elements in vector z are categorical rather than continuous values, you might want to consider using the group parameter to the plotting call as follows:
using Plots
# visualize x and y colouring points based on category z
scatter(x, y, group=z)