Is it possible to plot two implicit functions on the same canvas with sympys plot_implicit function?
E.g. have both lines from the two plots in the example be shown on one canvas.
from sympy import *
x,y = symbols('x y')
init_printing()
plot_implicit(Eq(abs(x)+abs(y), 1), (x,-1,1), (y, -1,1))
plot_implicit(Eq(x**2 + y**2, 1), (x,-1,1), (y, -1,1))
To combine two plots with sympy's plotting, the plots are first created with show=False, then appended and ultimately shown:
from sympy import symbols, plot_implicit, Eq, Abs
x, y = symbols('x y')
plot1 = plot_implicit(Eq(Abs(x) + Abs(y), 1), (x, -1, 1), (y, -1, 1),
line_color='steelblue', show=False)
plot2 = plot_implicit(Eq(x ** 2 + y ** 2, 1), (x, -1, 1), (y, -1, 1),
line_color='crimson', show=False)
plot1.append(plot2[0])
plot1.show()
Related
I want to make a plot using curve for multiple parameters.
For example, say I have the following distribution function for the binomial distribution:
I can plot curve for a probability mass function likeso:
curve(factorial(10)/(factorial(5)*factorial(5))*y^5*(1-y)^5, from=0, to = 1)
Because we want 0 < y < 1, however this won't work for multiple variables as from = 0, to = 1 will only apply for a single variable.
So - how can I get curve to work for something like:
curve(factorial(10)/(factorial(10-x)*factorial(x))*y^x*(1-y)^{10-x}, from=0, to = 1)
But also to indicate the the distribution function for x is less than or equal to 5, so from = 0, to = 5?
I guess you can use dbinom directly
curve(dbinom(5, 10, y), xname = "y")
or if you need to vary x, you can try
sapply(0:10, function(k) curve(dbinom(k, 10, y), xname = "y", add = TRUE, ylim = c(0, 1)))
You could loop over a sequence from 0 to 5.
curve(factorial(10)/(factorial(5)*factorial(5))*x^5*(1-x)^5, from=0, to=1,
ylim=c(0, 1), type='n')
invisible(lapply(seq.int(.005, 5, .005), \(y)
curve(factorial(10)/(factorial(10 - x)*factorial(x))*y^x*(1 - y)^{10 - x},
add=TRUE))
)
The invisible avoids cluttering of the console.
I know that you can transform the coordinates of a plot using coord_trans(), and you can even perform coordinate transformations along both axes (e.g. coord_trans(x = "log10", y = "log10")), but is there a way to perform a coordinate transformation that depends on the values of both axes, like a shear?
I know that I can perform the linear transformation before I pass my data to ggplot using something like ggforce::linear_trans() like this example:
trans <- linear_trans(shear(1, 0))
square <- data.frame(x = c(0, 0, 1, 1), y = c(0, 1, 1, 0))
square2 <- trans$transform(square$x, square$y)
ggplot(square2, aes(x, y)) +
geom_polygon(colour = 'black')
However, I'm hoping that there would be a way to write a custom coordinate system such that the data doesn't need to be transformed beforehand, e.g.:
square <- data.frame(x = c(0, 0, 1, 1), y = c(0, 1, 1, 0))
ggplot(square, aes(x, y)) +
geom_polygon(colour = 'black') +
coord_shear(x=1)
I implemented a custom coord that does this. It takes a transformer like that produced by ggforce::linear_trans and applies it to a ggplot. Check it out in my deeptime package here.
When two lines coincide, matplotlib uses the "sum" of the two line colours, while ggplot uses colour from one line. The matplotlib way makes it clearer that the two lines are overlapping. Is it possible to make ggplot do the similar colouring?
Setting alpha sort of does that, but with alpha, the resulting colour is dominated by the top colour. (If alpha = 0.5, then top colour gets opacity 0.5 and under colour gets opacity 0.5 * 0.5.)
matplotlib
pd.DataFrame({'A' : [0,1,2,3, 4], 'B' : [-1, 0, 2, 3, 0]}).plot(title = 'matplotlib in python')
ggplot
dt = data.table(name = rep(c('A','B'), each = 5),
y = c(0,1,2,3,4,-1, 0, 2, 3, 0),
x = 1:5)
ggplot(dt) +
geom_line(aes(x = x, y = y, col = name)) +
ggtitle('ggplot in R')
I have a plot(x, y) and I want to add a vertical line at x = 2 ONLY from y = 1 to 4. I want to use the lines() function but I'm having trouble limiting the y-range.
What's an easy way to do this?
Here's a simple example of using plot and lines. To draw a line from (2, 1) to (2, 4), you have to provide the x coordinates and y coordinates as (2, 2) and (1, 4):
plot(1:5)
lines(c(2, 2), c(1, 4))
ggplot2 offers a very simple solution, too!
library(ggplot2)
set.seed(1)
# Create some dummy data
data.frame(X = rpois(n = 10, lambda = 3),
Y = rpois(n = 10, lambda = 2)) %>%
# Pipe to ggplot
ggplot(aes(X, Y)) +
geom_point() +
geom_segment(aes(x = 1, xend = 1, y = 1, yend = 4), color = "red")
Within the aesthetics call to geom_segment() you can select the start and end points for your x and y parameters. You can then easily add multiple segments by simply adding + geom_segment(aes(...)) to the end of the code above.
For completeness, there is also a base graphics function in R that will do this: segments(x0,y0,x1,y1):
plot(1:5)
segments(2,1,2,4)
I was searching for a way to plot this function as a scalar field, in particular as continuous scalar field:
library(rgl)
points = seq(-2, 0, length=20)
XY = expand.grid(X=points,Y=-points)
Zf <- function(X,Y){
X^2-Y^2;
}
Z <- Zf(XY$X, XY$Y)
open3d()
rgl.surface(x=points, y=matrix(Z,20), coords=c(1,3,2),z=-points)
axes3d()
A scalar field is usually plotted with two axis X and Y, where Z is represent by a colour( http://en.wikipedia.org/wiki/Scalar_field)
With ggplot() I can do this:
daf=data.frame(XY$X,XY$Y,Z)
ggplot(daf)+geom_point(aes(XY.X,XY.Y,color=Z))
But still not a continuous field.
This can be achieved by the 'image' function:
Z <- outer(points, points, Zf)
image(points, points, Z)
This method just uses nearest neighbor interpolation, but if you want a smoother representation, you can use other types of interpolation:
library(fields)
# Bilinear interpolation
interp_points = seq(-2, 0, length = 200)
interp_bilinear <- interp.surface(list(x = X, y = Y, z = Z),
loc = expand.grid(interp_points, interp_points))
image(interp_points, interp_points, matrix(interp_bilinear, 200, 200))
# Bicubic interpolation
library(akima)
interp_bicubic <- bicubic.grid(X, Y, Z, xlim = c(-2, 0), ylim = c(-2, 0),
dx = 2 / (200 - 1), dy = 2 / (200 - 1))
image(interp_bicubic)
The difference between different interpolation schemes becomes clearer when you have fewer observations or more wildly behaving functions: