Related
Suppose I have the following data:
using DataFrames, CairoMakie, RDatasets
iris_df = dataset("datasets", "iris")[:, 1:4];
preds = rand((0, 1), 150)
Now I want to draw a scatter plot with a legend and arbitrary labels:
p = scatter(
iris_df[:, 2], iris_df[:, 3],
color=preds,
dpi=300,
)
Now I want to add a legend for it, But I'm unsuccessful.
What I've tried:
julia> Legend(p, ["label2", "label1"])
ERROR: MethodError: no method matching _block(::Type{Legend}, ::Makie.FigureAxisPlot, ::Vector{String})
Closest candidates are:
_block(::Type{<:Makie.Block}, ::Union{GridPosition, GridSubposition}, ::Any...; kwargs...) at C:\Users\Shayan\.julia\packages\Makie\Ggejq\src\makielayout\blocks.jl:287
_block(::Type{<:Makie.Block}, ::Union{Figure, Scene}, ::Any...; bbox, kwargs...) at C:\Users\Shayan\.julia\packages\Makie\Ggejq\src\makielayout\blocks.jl:298
Or:
f = Figure()
Axis(f[1, 1])
p = scatter!(
iris_df[:, 2], iris_df[:, 3],
color=preds,
dpi=300,
)
Legend(p, ["label2", "label1"])
ERROR: MethodError: no method matching _block(::Type{Legend}, ::Scatter{Tuple{Vector{Point{2, Float32}}}}, ::Vector{String})
Closest candidates are:
_block(::Type{<:Makie.Block}, ::Union{GridPosition, GridSubposition}, ::Any...; kwargs...) at C:\Users\Shayan\.julia\packages\Makie\Ggejq\src\makielayout\blocks.jl:287
_block(::Type{<:Makie.Block}, ::Union{Figure, Scene}, ::Any...; bbox, kwargs...) at C:\Users\Shayan\.julia\packages\Makie\Ggejq\src\makielayout\blocks.jl:298
Based on the maintainers' claim, this can't be done automatically yet. But one way is to can make the legend manually:
fig, ax, p = scatter(
iris_df[:, 2], iris_df[:, 3],
color=preds, dpi=300,
size=(50, 50),
)
elem_1, elem_2 = (
[
MarkerElement(
color = :black,
marker = :square,
markersize = 15
)
],
[
MarkerElement(
color = :yellow,
marker = :square,
markersize = 15
)
]
)
Legend(
fig[1, 2],
[elem_1, elem_2],
["label 1", "label 2"],
"Legend"
)
display(fig)
Helpful links: [1], [2]
I made a VennDiagram with five intersecting vectors, each containing a set of gene names.
Does anyone know whether I can somehow export the list of genes, which overlap in the different intersections?
I know I can do that with several online tools, such as Venny or InteractiVenn, but it would be much more convenient in R.
This is the code I use:
venn.diagram(
x = list(set1, set2, set3, set4, set5),
category.names = c("set1", "set2", "set3", "set4", "set5"),
filename= "my_path/venn.png",
output=NULL,
# # Output features
imagetype="png" ,
height = 2000 ,
width = 2000 ,
units = "px",
na = 'stop',
resolution = 300,
compression = "lzw",
lwd = 2,
col = c("#1ABC9C", "#85C1E9", "#CD6155", "#5B2C6F", "#F8C471"),
cat.col = c("#1ABC9C", "#85C1E9", "#CD6155", "#5B2C6F", "#F8C471"),
fill = c(alpha("#1ABC9C",0.3), alpha("#85C1E9",0.3), alpha("#CD6155",0.3), alpha("#5B2C6F",0.3), alpha("#F8C471",0.3)),
cex = 1.5,
fontfamily = "sans",
cat.cex = 1.15,
cat.default.pos = "text",
cat.fontfamily = "sans",
cat.dist= c(0.055),
cat.pos= c(1)
)
Thanks!
I suspect the OP has moved on, but I had the same question.
Here's what I came up with for a five set example- NB this uses a different package:
require(nVennR)
require(dplyr)
# wrangle input
Venn <- plotVenn(list("set1"=set1, "set2"=set2, "set3"=set3, "set4"=set4,
"set5"=set5), outFile = "DataSourceVenn.svg") # produces associated diagram
# generate lists of each intersect
intersects <- listVennRegions(Venn)
# pull lists together
intersects <- plyr::ldply(intersects, cbind)
# insert own appropriate col name for V1
colnames(intersects)<-c('Intersect','V1')
# transpose data into columns for each intersect
intersects <- dcast(setDT(intersects), rowid(Intersect) ~ Intersect, value.var =
"V1")[,Intersect:=NULL]
Looking for custom zticklabels and fontsize too on the z-axis. Most notably the intuitive approach of using zticks([-(R+r),0,R+r],["-R-r","0","R+r"],fontsize=16) does not work. I am using Julia 4.3.0 because this is an older project which I cannot fully convert to a newer version at this time. The commented lines below include additional commands I tried which were unsuccessful.
My final goal here is to get the -0.8, 0, 0.8 values on the z-axis to instead say "-r", and "0" and "r" respectively.
using PyPlot
colormapp = "nipy_spectral"
R = 1.6;
r = 0.8;
N = 256;
dx = 2*pi/(N-1);
y = zeros(N,1); # y = phi (col) toroidal
x = y.'; # x = theta (row) poloidal
for ix = 2:N; y[ix] = (ix-1)*dx; x[ix] = (ix-1)*dx; end
cosxsqr = cos(x) .+ 0.0*y;
sinxsqr = sin(x) .+ 0.0*y;
sinysqr = 0.0*x .+ sin(y);
cosysqr = 0.0*x .+ cos(y);
Rrcosxsqr = R+r*cosxsqr;
rRrcosx = r*Rrcosxsqr[:];
Xsqr = Rrcosxsqr.*cosysqr;
Ysqr = Rrcosxsqr.*sinysqr;
Zsqr = r*sinxsqr;
figure(98)
clf()
pmeshtor = pcolormesh(x,y,Zsqr+r,cmap=colormapp);
cb = colorbar();
colorvals = Zsqr+r;
colorvals = colorvals/maximum(colorvals[:])
ax = figure(99)
clf()
srf = surf(Xsqr,Ysqr,Zsqr,cstride=10,rstride=10,facecolors=get_cmap(colormapp).o((colorvals)))
cb = colorbar(pmeshtor,ticks=[0,0.8,1.6])
cb[:ax][:set_yticklabels](["-r","0","r"], fontsize=16)
xlabel("x",fontsize=16)
ylabel("y",fontsize=16)
zlabel("z",fontsize=16)
xlim([-(R+r)-0.3,R+r+0.3])
ylim([-(R+r)-0.3,R+r+0.3])
zlim([-(R+r)-0.3,R+r+0.3])
xticks([-(R+r),0,R+r],["-R-r","0","R+r"],fontsize=16)
yticks([-(R+r),0,R+r],["-R-r","0","R+r"],fontsize=16)
zticks([-r,0,r])
#zticklabels([-r,0,r],["-r","0","r"])
#setp(ax[:get_zticklabels](),fontsize=16);
#setp(ax[:set_zticklabels](["-r","0","r"]))#,fontsize=16);
Here is the resulting image.
The commented command
setp(ax[:set_zticklabels](["-r","0","r"]),fontsize=16);
does work, but only if insert missing projection option as follows in Fig 99
figure(99)
ax = subplot(111, projection="3d")
I have 3 different rasters in a stack. I need to plot a panel plot and add different shapefiles on each panel. So far I managed to do the following;
## read the libraries
library(raster)
library(rgdal)
library(sp)
library(rworldmap)
library(OceanView)
##random raster object
r <- raster(ncol=40, nrow=20)
r[] <- rnorm(n=ncell(r))
# Create a RasterStack object with 3 layers
s <- stack(x=c(r, r*2, r**2))
##coordinate system
wgs<-CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs")
##reading the additional shape files
w <- spTransform(getMap(), wgs)
poly <- list(list("sp.lines", as(w, 'SpatialLines'), lwd =
0.5,col="black"))
##plotting with spplot
plot(spplot(s,layout=c(3,1),sp.layout=poly,
colorkey =list(space = "right"),
names.attr = c("a","b","c")))
so far I plotted the 3 rasters with a shapefile overlayed on it. Now I need to plot the 3 different contours one each on the panel plot. And also need to plot the windspeed arrows on each of the plot. I know to do this I need to use contour() and quiver() functions. However, I am unable to plot these.
## different raster stack for the contour plot
s1 <- stack(x=c(r/2, r*10, r**5))
##differnt wind components
lat= matrix(rep(seq(-90,90,length.out=20),each=20), ncol=20, byrow=TRUE)
lon=matrix(rep(seq(-180,180,length.out=20),each=20), ncol=20, byrow=F)
u=matrix(rep(sample(seq(-2,2,length.out=1000),20),each=20), ncol=20, byrow=TRUE)
v=matrix(rep(sample(seq(-2,2,length.out=1000),20),each=20), ncol=20, byrow=TRUE)
##plot the arrows
quiver2D(u = u,v=v,x = lon, y = lat,add=T,type="simple")
can any one help me with this? Any help would be appreciated.
First you need to figure out which function in the lattice paradigm is being called. That requires either looking at the ?spplot` help page (which I stupidly failed to do first), or following the classes and functions along the calling tree (which is what I actually did). And then look at the help page of the final function to see if there is a parameter you can pass to add contour lines:
showMethods("spplot",class="Raster", includeDefs=TRUE) # last argument need to see code
Function: spplot (package sp)
obj="Raster"
function (obj, ...)
{
.local <- function (obj, ..., maxpixels = 50000, as.table = TRUE,
zlim)
{
obj <- sampleRegular(obj, maxpixels, asRaster = TRUE,
useGDAL = TRUE)
if (!missing(zlim)) {
if (length(zlim) != 2) {
warning("zlim should be a vector of two elements")
}
if (length(zlim) >= 2) {
obj[obj < zlim[1] | obj > zlim[2]] <- NA
}
}
obj <- as(obj, "SpatialGridDataFrame")
spplot(obj, ..., as.table = as.table)
}
.local(obj, ...)
}
> showMethods("spplot",class="SpatialGridDataFrame",includeDefs=TRUE)
Function: spplot (package sp)
obj="SpatialGridDataFrame"
function (obj, ...)
spplot.grid(as(obj, "SpatialPixelsDataFrame"), ...)
> showMethods("spplot.grid",class="SpatialPixelsDataFrame",includeDefs=TRUE)
Function "spplot.grid":
<not an S4 generic function>
> spplot.grid
Error: object 'spplot.grid' not found
> getAnywhere(spplot.grid)
A single object matching ‘spplot.grid’ was found
It was found in the following places
namespace:sp
with value
function (obj, zcol = names(obj), ..., names.attr, scales = list(draw = FALSE),
xlab = NULL, ylab = NULL, aspect = mapasp(obj, xlim, ylim),
panel = panel.gridplot, sp.layout = NULL, formula, xlim = bbox(obj)[1,
], ylim = bbox(obj)[2, ], checkEmptyRC = TRUE, col.regions = get_col_regions())
{
if (is.null(zcol))
stop("no names method for object")
if (checkEmptyRC)
sdf = addNAemptyRowsCols(obj)
else sdf = as(obj, "SpatialPointsDataFrame")
if (missing(formula))
formula = getFormulaLevelplot(sdf, zcol)
if (length(zcol) > 1) {
sdf = spmap.to.lev(sdf, zcol = zcol, names.attr = names.attr)
zcol2 = "z"
}
else zcol2 = zcol
if (exists("panel.levelplot.raster")) {
opan <- lattice.options("panel.levelplot")[[1]]
lattice.options(panel.levelplot = "panel.levelplot.raster")
}
scales = longlat.scales(obj, scales, xlim, ylim)
args = append(list(formula, data = as(sdf, "data.frame"),
aspect = aspect, panel = panel, xlab = xlab, ylab = ylab,
scales = scales, sp.layout = sp.layout, xlim = xlim,
ylim = ylim, col.regions = col.regions), list(...))
if (all(unlist(lapply(obj#data[zcol], is.factor)))) {
args$data[[zcol2]] = as.numeric(args$data[[zcol2]])
if (is.null(args$colorkey) || (is.logical(args$colorkey) &&
args$colorkey) || (is.list(args$colorkey) && is.null(args$colorkey$at) &&
is.null(args$colorkey$labels))) {
if (!is.list(args$colorkey))
args$colorkey = list()
ck = args$colorkey
args$colorkey = NULL
args = append(args, colorkey.factor(obj[[zcol[1]]],
ck))
}
else args = append(args, colorkey.factor(obj[[zcol[1]]],
ck, FALSE))
}
ret = do.call(levelplot, args)
if (exists("panel.levelplot.raster"))
lattice.options(panel.levelplot = opan)
ret
}
<bytecode: 0x7fae5e6b7878>
<environment: namespace:sp>
You can see that it supports additional arguments passed via , list(...)). As it happens it's therefore fairly easy to add contour lines to a levelplot with contour=TRUE although that only appears in the Arguments list, but not in the named arguments in the Usage section for levelplot. Nonetheless testing in the example on ?levelplot page shows that it succeeds. Your example is not a particularly good one to illustrate with, since it is so fine-grained and has no pattern of ascending or descending levels. Nonetheless adding contour=TRUE, to the arguments to spplot does produce black contour lines. (The timestamp is due to lattice code in my Rprofile setup so won't show up on your device).
png(); plot(spplot(s,layout=c(3,1),sp.layout=poly, contour=TRUE,
colorkey =list(space = "right"),
names.attr = c("a","b","c"))) ; dev.off()
If one gets around to hacking spplot.grid or perhaps sp::panel.gridplot, then this material from the author of levelplot might be of use:
https://markmail.org/search/?q=list%3Aorg.r-project.r-help+lattice+add+contours+to+levelplot#query:list%3Aorg.r-project.r-help%20lattice%20add%20contours%20to%20levelplot%20from%3A%22Deepayan%20Sarkar%22+page:1+mid:w7q4l7dh6op2lfmt+state:results
I'm plotting legs of a route to a ggmap. It works okay so far. I've been trying to add a label containing the order (n from the loop) of each leg.
I've tried +geom_text to the geom_leg() but I get the error :
Error in geom_leg(aes(x = startLon, y = startLat, xend = endLon, yend = endLat), :
non-numeric argument to binary operator
I'd appreciate any help adding a label to indicate the leg.
Data :
structure(c("53.193418", "53.1905138631287", "53.186744", "53.189836",
"53.1884117", "53.1902965", "53.1940384", "53.1934748", "53.1894004",
"53.1916771", "-2.881248", "-2.89043889005541", "-2.890165",
"-2.893896", "-2.88802", "-2.8919373", "-2.8972299", "-2.8814698",
"-2.8886692", "-2.8846099"), .Dim = c(10L, 2L))
Function :
create.map<-function(lst){
library("ggmap")
cncat<-c(paste(lst[,1],lst[,2],sep=","))
df2<-data.frame(cncat)
leg <-function(start, dest, order){
r<- route(from=start,to=dest,mode = c("walking"),structure = c("legs"))
c<- geom_leg(aes(x = startLon, y = startLat,xend = endLon, yend = endLat),
alpha = 2/4, size = 2, data = r,colour = 'blue')+
geom_text(aes(label = order), size = 3)
return (c)
}
a<-qmap('Chester, UK', zoom = 15, maptype = 'road')
for (n in 1:9){
l<-leg(as.character(df2[n,1]), as.character(df2[n+1,1]),n)
a<-a+l
}
a
}
Is this close? (Note: this calls your list of points way.points).
way.points <- as.data.frame(way.points,stringsAsFactors=FALSE)
library(ggmap)
rte.from <- apply(way.points[-nrow(way.points),],1,paste,collapse=",")
rte.to <- apply(way.points[-1,],1,paste,collapse=",")
rte <- do.call(rbind,
mapply(route, rte.from, rte.to, SIMPLIFY=FALSE,
MoreArgs=list(mode="walking",structure="legs")))
coords <- rbind(as.matrix(rte[,7:8]),as.matrix(rte[nrow(rte),9:10]))
coords <- as.data.frame(coords)
ggm <- qmap('Chester, UK', zoom = 15, maptype = 'road')
ggm +
geom_path(data=coords,aes(x=startLon,y=startLat),color="blue",size=2)+
geom_point(data=way.points,aes(x=as.numeric(V2),y=as.numeric(V1)),
size=10,color="yellow")+
geom_text(data=way.points,
aes(x=as.numeric(V2),y=as.numeric(V1), label=seq_along(V1)))
So this assembles a vector of from and to coordinates using apply(...), then uses mapply(...) to call route(...) with both vectors, returning the overall list of coordinates in a data frame rte. Because the coordinates are stored as, e.g. $startLat and $endLat, we form a coords data frame by adding the final $endLat and $endLong to rte to get the very last leg of the route. Then we use geom_path(...) to draw the path in one step. Finally we use geom_text(...) with x and y-values from the original way.points data frame, and we use geom_point(...) just to make them stand out a bit.
Here's a bare bones solution. I just added the labels to the finished ggmap object a. If you replace the line
a
with
lst2 <- data.frame(cbind(lst, leg = as.character(1:10) )
names(lst2) <- c("lat", "lon", "leg")
a <- a + geom_text(data=lst2,aes(x=lon,y=lat,label=leg),size=5, vjust = 0, hjust = -0.5)
return(a)
in your create.map function, you should get (roughly) the desired result. I might have reversed the lat and lon variables, and you probably want to tweak the size, location, etc. Hope this helps!