Suppose we have couple of linear inequalities like 2x-5y<=6 and x+y>=0, how do we plot the two inequalities? To extend this, if we have multiple such inequalities how do we try to solve this graphically?
You can try ImplicitEquations:
using ImplicitEquations, Plots
f(x,y) = 2x - 5y - 6
g(x,y) = x + y - 0
plot((f < 0) & (g > 0))
Resulting in the region over the default rectangle [-5,5], [-5,5]:
Isolating y shows us that both are inequalities of the form y>=ax+b. This means that we can plot the inequalities using plots, functions for the equality versions, and the maximum values the function obtains on the intervals.
using Plots
f(x) = (2/5)x-6/5
g(x) = -x
X = -10:10
the_max = max(f(X[end]), g(X[1]))
plot(X, f, fill = (the_max, 0.5, :auto))
plot!(X, g, fill = (the_max, 0.5, :auto))
Which gives us
Had the second equation had its inequality flipped, we would have
using Plots
f(x) = (2/5)x-6/5
g(x) = -x
X = -10:10
the_max = max(f(X[end]), g(X[1]))
the_min = min(f(X[1]), g(X[end]))
plot(X, f, fill = (the_max, 0.5, :auto))
plot!(X, g, fill = (the_min, 0.5, :auto))
Obviously, you would want to automate the precedure of finding the min and max if there were many such inequalities to plot. Also, this rewriting depends on the linearity, but your question specifically mentioned they were linear.
You can make a matrix of x and y on the interval you want to plot (using a version of meshgrid), and then let u=(2x-5y.<=6) and v=(x+y.>=0). Then u will be 1 when the equation is satisfied, same for v. You can use a heatmap, contour plot, or scatter plot from Plots.jl to then plot the (x,y,u) and (x,y,v) (you will see if you chose a fine enough grid by how coarse the plot is). For the overlap, you can plot z=(u.==v).
Have a look at IntervalConstraintProgramming.jl (still very much a work in progress...)
Related
I have a time series that I'd like to plot using the polygon function as I want to create a shade between different time series. However, when calling polygon (), the function adds a line between the first and last point (in essence it connects the first and last point to finish the plot). I would like to know how to tell R not to join up the two. Slightly related questions have been posted (Line connecting the points in the plot function in R) but the solutions didn't help. Any help would be appreciated.
I have already tried several things, such as reordering the data like in the part below.
% ts_lb_vec is my time-series in vector format;
% x is a vector of time (2000 to 2015);
% I first call plot which plots x (time) with y (the time-series). This works fine;
plot(x, ts_lb_vec,type='n',ylim=c(-300,300), ylab="", xlab="")
But if I want to use the polygon function to use the shading capabilities, it draws the line and I have tried reordering the data (as below) to try to eliminate the problem but this is unsuccessful
polygon(x[order(x),ts_lb_vec[order(x)], xlim=range(x), ylim=range(ts_lb_vec))
I would just like R when calling the polygon function to not connect my first and last point (see image). The figure attached bellow was produced using the following code:
plot(x, ts_lb_vec,type='n', ylab="", xlab="")
polygon(x, ts_lb_vec)
Just to clarify, what I would like is for the space between two time series to be filled, hence why I need the function polygon. See image below
I put together a solution using ggplot2.
The key step is drawing a separate polygon where the order of one of the curves is inverted to avoid the crossing over back to the start.
# simple example data
examp.df <- data.frame(time = seq_len(15), a = c(1,2,3,4,5,5,5,4,3,2,4,5,6,7,8), b = c(2,4,5,6,7,8,7,6,6,5,6,4,3,2,1))
# the polygon is generated by inverting the curve b
polygon <- data.frame(time <- c(examp.df$time, rev(examp.df$time)), y.pos = c(examp.df$a, rev(examp.df$b)))
ggplot(examp.df) +
geom_polygon(data = polygon, aes(x = time, y = y.pos), fill = "blue", alpha = 0.25) +
geom_line(aes(x= time, y = a), size = 1, color = "red") +
geom_line(aes(x = time, y = b), size = 1, color = "green") +
theme_classic()
Which results in:
If you want to know more about ggplot2 this is a good introduction.
I am trying to do the following:
plot a time series in R using a polygonal line
plot one or more horizontal lines superimposed
find the intersections of said line with the orizontal ones
I got this far:
set.seed(34398)
c1 <- as.ts(rbeta(25, 33, 12))
p <- plot(c1, type = 'l')
# set thresholds
thresholds <- c(0.7, 0.77)
I can find no way to access the segment line object plotted by R. I really really really would like to do this with base graphics, while realizing that probably there's a ggplot2 concoction out there that would work. Any idea?
abline(h=thresholds, lwd=1, lty=3, col="dark grey")
I will just do one threshold. You can loop through the list to get all of them.
First find the points, x, so that the curve crosses the threshold between x and x+1
shift = (c1 - 0.7)
Lower = which(shift[-1]*shift[-length(shift)] < 0)
Find the actual points of crossing, by finding the roots of Series - 0.7 and plot
shiftedF = approxfun(1:length(c1), c1-0.7)
Intersections = sapply(Lower, function(x) { uniroot(shiftedF, x:(x+1))$root })
points(Intersections, rep(0.7, length(Intersections)), pch=16, col="red")
I am attempting to plot discrete functions in R for a flow model equation. I have to plot the original function u(x) = tanh(x - 0.1), with u(x) on the Y-axis and x on the X-axis. I then must plot a discrete function that describes the slope.
u <- array(0,dim=c(21))
#Plot the original function u(x)=tanh(ax-x0)
curve(tanh(x-0.1), from=0, to=5, n=100, col="red", xlab="x", ylab = "u(x)")
grid (NULL,NULL, col = "lightgray", lty="dotted")
x = seq(0, 5, by=0.25)
for (i in 1:21){
u[i] = tanh(x[i]-0.1)
}
x1 = seq(0, 4.75, by=0.25)
du1 <- array(0,dim=c(20))
for (i in 1:20){
du1[i] = (u[i+1]-u[i])/0.25
}
plot(x1, du1, xlab = "x", ylab = "du/dx")
So per the definition of my derivative function, my du/dx vector will only have 20 vector points, but my x vector still has 21 points. I must then repeat giving defined du/dx vectors that have 19 and 18 vector points. Is there any way I can plot the du/dx vs. x functions all on the same graph without having to redefine x every time?
I'm not sure I'm totally clear on what you're asking, but here's code that prevents you from writing out 18 individual code blocks (using the "diff" function in base).
derivs <- matrix(NA, nrow=21, ncol=18)
x <- seq(0, 5, by=0.25)
orig <- tanh(x-0.1)
derivs[,1] <- c(diff(orig)/.25, NA)
for(col in 2:18) {
print(col)
derivs[,col] <- c((diff(derivs[,col-1])/.25), NA)
}
The resulting matrix (here called "derivs" has a column for each derivative (first column is first derivative, second is second derivative, etc...)
One reason I'm a bit confused about what you're trying for is that, if you were to plot all these on one graph, it would be a really weird graph, because the order of magnitudes are really different between the first few, and the last few derivatives.
The dimensions aren't really different for each derivative; I've simply padded it with NAs, which won't appear on a graph.
Also note that you can use the diff function to get second-order differences and so forth.
PS. The graph will probably look more reasonable if, rather than taking the differences as you did (and as I did, to emulate you), so that the different is assigned to the first x value...you probably want to center. E.g. every other derivative would actually be plotted at .125, .375, etc.)
I am trying to smooth my data set, using kernel or loess smoothing method. But, They are all not clear or not what I want. Several questions are the followings.
My x data is "conc" and y data is "depth", which is ex. cm.
1) Kernel smooth
k <- kernel("daniell", 150)
plot(k)
K <- kernapply(conc, k)
plot(conc~depth)
lines(K, col = "red")
Here, my data is smoothed by frequency=150. This means that every data point is averaged by neighboring (right and left) 150 data points? What "daniell" means? I could not find what it means online.
2) Loess smooth
p<-qplot(depth, conc, data=total)
p1 <- p + geom_smooth(method = "loess", size = 1, level=0.95)
Here, what is the default of loess smooth function? If I want to smooth my data with frequency=150 like above case (moving average by every 150 data point), how can I modify this code?
3) To show y-axis with log scale, I put "log10(conc)", instead of "conc", and it worked. But, I cannot change the y-axis tick label. I tried to use "scale_y_log10(limits = c(1,1e3))" in my code to show axis tick labe like 10^0, 10^1, 10^2..., but did not work.
Please answer my questions. Thanks a lot for your help.
Sum
I have the following data in a data frame:
**x** in (0,1)
**y** in [0,1]
**z** in [0,1]
For example:
X,Y,Z
0.1, 0.2, 0.56
0.1, 0.3, 0.57
...
I'd like to plot them on this type of chart:
I tried on R, but all I could get was a not-so-fancy 3d scatterplot.
I also read about the lattice 3d wireframe, but I couldn't get my head around it.
What am I supposed to do to get a Matlab like wireframe in R?
What data transforms are involved?
This is the sample code from the documentation:
x <- seq(-pi, pi, len = 20)
y <- seq(-pi, pi, len = 20)
g <- expand.grid(x = x, y = y)
g$z <- sin(sqrt(g$x^2 + g$y^2))
wireframe(z ~ x * y, g, drape = TRUE,
aspect = c(3,1), colorkey = TRUE)
I don't find it particularly clear.
EDIT: the persp3d function works fine, and I was able to generate a 3d plot with one colour. How can I set a colour scale relative to the z value?
Thanks for any hints,
Mulone
Use outer to create the z values and then use persp to plot:
z <- outer(x,y, function(x,y) sin(sqrt(x^2+y^2)))
persp(x,y,z)
There are options for colouring and setting the viewing angle, see ?persp. See the fourth example for Matlab style colouring.
For an interactive plot, consider using persp3d in the rgl package:
require(rgl)
persp3d(x,y,z,col="blue")
Edit
To add colour, there is a slight difference from the method in persp, since the colour relates to the vertex rather than the centre of the facet, but it makes it easier.
jet.colors <- colorRampPalette( c("blue", "green") )
pal <- jet.colors(100)
col.ind <- cut(z,100) # colour indices of each point
persp3d(x,y,z,col=pal[col.ind])
The help file recommends adding the parameter smooth=FALSE, but that's down to personal preference.