Downloaded Julia 15 min ago and thought I would play around.
I keep getting this error: syntax: missing comma or ) in argument list
using Pkg
Pkg.add("CSV")
Pkg.add("DataFrames")
Pkg.add("Plots")
using CSV
using DataFrames
using Plots
iris = CSV.read("julia/iris.csv", normalizenames = true)
histogram(
iris.sepal_length,
title = "This is my first Julia graph",
label = "size",
xlabel "X",
ylabel = "Y"
)
Have restarted kernel and written like matplot and seaborne, still getting error.
Also:
Updating registry at ~/.julia/registries/General
Resolving package versions...
No Changes to ~/.julia/environments/v1.5/Project.toml
No Changes to ~/.julia/environments/v1.5/Manifest.toml
Resolving package versions...
No Changes to ~/.julia/environments/v1.5/Project.toml
No Changes to ~/.julia/environments/v1.5/Manifest.toml
Resolving package versions...
No Changes to ~/.julia/environments/v1.5/Project.toml
No Changes to ~/.julia/environments/v1.5/Manifest.toml
Seems fine. Any ideas?
Thanks guys!
#Edit: Also, this code:
p1 = scatter(iris.petal_length)
p2 = histogram(iris.petal_width)
p3 = histogram(iris.sepal_length)
p4 = scatter(iris.sepal_width)
plot = (p1, p2, p3, p4, layout = (2, 2), legend = false)
print(plot)
returns:
(p1 = Plot{Plots.GRBackend() n=1}, p2 = Plot{Plots.GRBackend() n=1}, p3 = Plot{Plots.GRBackend() n=1}, p4 = Plot{Plots.GRBackend() n=1}, layout = (2, 2), legend = false)
??????????
You first error is:
xlabel "X",
which should be
xlabel = "X",
Your second error is that you are creating your final plot by putting p1 to p4 into a NamedTuple, rather than plotting them. You should be doing:
plot(p1, p2, p3, p4, layout = (2, 2), legend = false)
i.e. call the plot function with your subplots as arguments. Instead you are doing:
(p1, p2, p3, p4, layout = (2, 2), legend = false)
which is the Julia syntax for creating a NamedTuple, compare:
julia> (a = 1, b = "letters", c = false)
(a = 1, b = "letters", c = false)
julia> typeof(ans)
NamedTuple{(:a, :b, :c),Tuple{Int64,String,Bool}}
Related
I have an existing plotting function (perhaps written by someone else) that uses mfrow to plot multiple figures on the same graphics device. I want to edit figures that have already been plotted (e.g. perhaps add a reference line to figure 1)
par(mfrow = c(1, 2))
plot(1:10)
hist(1:10)
# Oh no! I want to add abline(a = 0, b = 1) to the first plot!
Assume this code is nested in another plotting function
PlotABunchOfStuff(1:10) that I can't modify.
I don't want to modify PlotABunchOfStuff because someone else owns it, or I'm just debugging and won't need the extra details once the bug is found.
Use par(mfg).
For example:
par(mfrow = c(2, 3))
for (i in 1:6) {
plot(i, xlim = c(0,7), ylim = c(0, 7))
}
par(mfg = c(2, 2))
points(3,3,col= "red")
par(mfg = c(1, 1))
points(3,3,col= "blue")
If you are ready to use ggplot I think you can find what you want in the code below :
df <- data.frame(x = 1:10, y = 1:10)
g1 <- ggplot(df, aes(x = x, y = y)) +
geom_point()
g2 <- ggplot(df, aes(x = x, y = y)) +
geom_line()
grid.arrange(g1, g2)
g1 <- g1 + geom_smooth(method='lm',formula=y~x) # it could be anything else !
grid.arrange(g1, g2)
Edit 1
Create a graphical object in windows which will be destroye after dev.off() if filename = "" :
win.metafile(filename = "")
By default inhibit doesn't allow the plot to be recorded so we use enable :
dev.control('enable')
plot(1:10)
p <- recordPlot()
dev.off()
replayPlot(p)
p
abline(a = 1, b = 1, col = "red")
p <- recordPlot()
dev.off()
replayPlot(p)
My inspirations on Stackoverflow :
R plot without showing the graphic window
Save a plot in an object
My inspirations on R :
https://www.rdocumentation.org/packages/grDevices/versions/3.6.0/topics/dev
https://www.rdocumentation.org/packages/grDevices/versions/3.6.0/topics/recordPlot
I hope it helps you ! Good luck.
Be careful with scaling!
For the example in the original question, this will not have the result I think is desired.
par(mfrow = c(1, 2))
plot(1:10)
hist(1:10)
par(mfg = c(1, 1))
abline(a = 0, b = 1)
But this will have the result I think is desired.
par(mfrow = c(1, 2))
plot(1:10)
hist(1:10)
par(mfg = c(1, 1))
plot.window(xlim = c(1, 10), ylim = c(1, 10))
abline(a = 0, b = 1)
The mfg graphics parameter will allow you to jump to any panel, but the window scaling may need to be adjusted to be appropriate for the scale used when the original plot was created in that panel.
I have drawn heatmap in biclust package using the following code, but I couldn't find any option for adding row and column names.
library(biclust)
set.seed(1234)
data(BicatYeast)
resplaid <- biclust(BicatYeast, BCBimax(), verbose = FALSE)
heatmapBC(x = BicatYeast, bicResult = resplaid)
How can I draw them?
Here a solution. Looking at the heatmapBC function you see that axes as set as FALSE by default!
You will be able to put your labels both in the rows and columns of your heatmap by using the axis command.
I've used a subsetted version of BicatYeast data for making plots clearer
library(biclust)
set.seed(1234)
data(BicatYeast)
d <- as.matrix(BicatYeast)[1:30, 1:20]; d
resplaid <- biclust(d, BCBimax())
par(mar=c(10, 6, 2, 2) + 0.1)
heatmapBC(x = d, bicResult = resplaid, axes = F, xlab = "", ylab = "")
axis(1, at=1:dim(d)[2], labels = colnames(d), las=2)
axis(2, at=1:dim(d)[1], labels = rownames(d), las=2)
I am trying to create a data table whose cells are different colors based on the value in the cell. I can achieve this with the function addtable2plot from the plotrix package. The addtable2plot function lays a table on an already existing plot. The problem with that solution is that I don't want a plot, just the table.
I've also looked at the heatmap functions. The problem there is that some of the values in my table are character, and the heatmap functions, from what I can tell, only accept numeric matrices. Also, I want my column names to be at the top of the table, not the bottom, and that doesn't seem to be an option.
Here's the example code for addtable2plot. If I could get just the table, filling the whole screen, that would be great.
library(plotrix)
testdf<-data.frame(Before=c(10,7,5,9),During=c(8,6,2,5),After=c(5,3,4,3))
rownames(testdf)<-c("Red","Green","Blue","Lightblue")
barp(testdf,main="Test addtable2plot",ylab="Value",
names.arg=colnames(testdf),col=2:5)
# show most of the options including the christmas tree colors
abg<-matrix(c(2,3,5,6,7,8),nrow=4,ncol=3)
addtable2plot(2,8,testdf,bty="o",display.rownames=TRUE,hlines=TRUE,
vlines=TRUE,title="The table",bg=abg)
Any help would be greatly appreciated.
A heatmap alternative:
library(gplots)
# need data as matrix
mm <- as.matrix(testdf, ncol = 3)
heatmap.2(x = mm, Rowv = FALSE, Colv = FALSE, dendrogram = "none",
cellnote = mm, notecol = "black", notecex = 2,
trace = "none", key = FALSE, margins = c(7, 11))
In heatmap.2 the side of the plot the axis is to be drawn on is hard-coded. But if you type "heatmap.2" at the console and copy the output to an editor, you can search for axis(1, where the 1 is the side argument (two hits). You can then change from a 1 (axis below plot) to a 3 (axis above the plot). Assign the updated function to a new name, e.g. heatmap.3, and run it as above.
An addtable2plot alternative
library(plotrix)
# while plotrix is loaded anyway:
# set colors with color.scale
# need data as matrix*
mm <- as.matrix(testdf, ncol = 3)
cols <- color.scale(mm, extremes = c("red", "yellow"))
par(mar = c(0.5, 1, 2, 0.5))
# create empty plot
plot(1:10, axes = FALSE, xlab = "", ylab = "", type = "n")
# add table
addtable2plot(x = 1, y = 1, table = testdf,
bty = "o", display.rownames = TRUE,
hlines = TRUE, vlines = TRUE,
bg = cols,
xjust = 2, yjust = 1, cex = 3)
# *According to `?color.scale`, `x` can be a data frame.
# However, when I tried with `testdf`, I got "Error in `[.data.frame`(x, segindex) : undefined columns selected".
A color2D.matplot alternative
library(plotrix)
par(mar = c(0.5, 8, 3.5, 0.5))
color2D.matplot(testdf,
show.values = TRUE,
axes = FALSE,
xlab = "",
ylab = "",
vcex = 2,
vcol = "black",
extremes = c("red", "yellow"))
axis(3, at = seq_len(ncol(testdf)) - 0.5,
labels = names(testdf), tick = FALSE, cex.axis = 2)
axis(2, at = seq_len(nrow(testdf)) -0.5,
labels = rev(rownames(testdf)), tick = FALSE, las = 1, cex.axis = 2)
After this little exercise, I tend to agree with #Drew Steen that LaTeX alternatives may be investigated as well. For example, check here and here.
You can hack something with grid and gtable,
palette(c(RColorBrewer::brewer.pal(8, "Pastel1"),
RColorBrewer::brewer.pal(8, "Pastel2")))
library(gtable)
gtable_add_grobs <- gtable_add_grob # alias
d <- head(iris, 3)
nc <- ncol(d)
nr <- nrow(d)
extended_matrix <- cbind(c("", rownames(d)), rbind(colnames(d), as.matrix(d)))
## text for each cell
all_grobs <- matrix(lapply(extended_matrix, textGrob), ncol=ncol(d) + 1)
## define the fill background of cells
fill <- lapply(seq_len(nc*nr), function(ii)
rectGrob(gp=gpar(fill=ii)))
## some calculations of cell sizes
row_heights <- function(m){
do.call(unit.c, apply(m, 1, function(l)
max(do.call(unit.c, lapply(l, grobHeight)))))
}
col_widths <- function(m){
do.call(unit.c, apply(m, 2, function(l)
max(do.call(unit.c, lapply(l, grobWidth)))))
}
## place labels in a gtable
g <- gtable_matrix("table", grobs=all_grobs,
widths=col_widths(all_grobs) + unit(4,"mm"),
heights=row_heights(all_grobs) + unit(4,"mm"))
## add the background
g <- gtable_add_grobs(g, fill, t=rep(seq(2, nr+1), each=nc),
l=rep(seq(2, nc+1), nr), z=0,name="fill")
## draw
grid.newpage()
grid.draw(g)
Sort of a hacky solution based on ggplot2. I don't totally understand how you actually want to map your colors, since in your example the colors in the table are not mapped to the rownames of testdf, but here I've mapped the colors to the value (converted to a factor).
testdf$color <- rownames(testdf)
dfm <- melt(testdf, id.vars="color")
p <- ggplot(dfm, aes(x=variable, y=color, label=value, fill=as.factor(value))) +
geom_text(colour="black") +
geom_tile(alpha=0.2)
p
You can change what variable the values are mapped to using fill=, and you can change the mapping using scale_fill_manual(values=[a vector of values].
That said, I'd be curious to see a solution that produces an actual table, rather than a plot masquerading as a table. Possibly using Sweave and LaTeX tables?
I found many resources on how to draw Venn diagrams in R. Stack Overflow has a lot of them. However, I still can't draw my diagrams the way I want. Take the following code as an example:
library("VennDiagram")
A <- 1:4
B <- 3:6
d <- list(A, B)
vp <- venn.diagram(d, fill = c("white", "white"), alpha = 1, filename = NULL,
category.names=c("A", "B"))
grid.draw(vp)
I want the intersection between the sets to be red. However, if I change any of the white colors to red, I get the following:
vp_red <- venn.diagram(d, fill = c("red", "white"), alpha = 1, filename = NULL,
category.names=c("A", "B"))
grid.draw(vp_red)
That's not quite what I want. I want only the intersection to be red. If I change the alpha, this is what I get:
vp_alpha <- venn.diagram(d, fill = c("red", "white"), alpha = 0.5, filename = NULL,
category.names=c("A", "B"))
grid.draw(vp_alpha)
Now I have pink in my intersection. This is not what I want as well. What I want is something like this image from Wikipedia:
How can I do this? Maybe VennDiagram package can't do it and I need some other package, but I've been testing different ways to do it, and I'm not being able to find a solution.
I will show two different possibilities. In the first example, polyclip::polyclip is used to get the intersection. In the second example, circles are converted to sp::SpatialPolygons and we get the intersection using rgeos::gIntersection. Then we re-plot the circles and fill the intersecting area.
The resulting object when using venn.diagram is
"of class gList containing the grid objects that make up the diagram"
Thus, in both cases we can grab relevant data from "vp". First, check the structure and list the grobs of the object:
str(vp)
grid.ls()
# GRID.polygon.234
# GRID.polygon.235
# GRID.polygon.236 <~~ these are the empty circles
# GRID.polygon.237 <~~ $ col : chr "black"; $ fill: chr "transparent"
# GRID.text.238 <~~ labels
# GRID.text.239
# GRID.text.240
# GRID.text.241
# GRID.text.242
1. polyclip
Grab x- and y-values, and put them in the format required for polyclip:
A <- list(list(x = as.vector(vp[[3]][[1]]), y = as.vector(vp[[3]][[2]])))
B <- list(list(x = as.vector(vp[[4]][[1]]), y = as.vector(vp[[4]][[2]])))
Find intersection:
library(polyclip)
AintB <- polyclip(A, B)
Grab labels:
ix <- sapply(vp, function(x) grepl("text", x$name, fixed = TRUE))
labs <- do.call(rbind.data.frame, lapply(vp[ix], `[`, c("x", "y", "label")))
Plot it!
plot(c(0, 1), c(0, 1), type = "n", axes = FALSE, xlab = "", ylab = "")
polygon(A[[1]])
polygon(B[[1]])
polygon(AintB[[1]], col = "red")
text(x = labs$x, y = labs$y, labels = labs$label)
2. SpatialPolygons and gIntersection
Grab the coordinates of the circles:
# grab x- and y-values from first circle
x1 <- vp[[3]][["x"]]
y1 <- vp[[3]][["y"]]
# grab x- and y-values from second circle
x2 <- vp[[4]][["x"]]
y2 <- vp[[4]][["y"]]
Convert points to SpatialPolygons and find their intersection:
library(sp)
library(rgeos)
p1 <- SpatialPolygons(list(Polygons(list(Polygon(cbind(x1, y1))), ID = 1)))
p2 <- SpatialPolygons(list(Polygons(list(Polygon(cbind(x2, y2))), ID = 2)))
ip <- gIntersection(p1, p2)
Plot it!
# plot circles
plot(p1, xlim = range(c(x1, x2)), ylim = range(c(y1, y2)))
plot(p2, add = TRUE)
# plot intersection
plot(ip, add = TRUE, col = "red")
# add labels (see above)
text(x = labs$x, y = labs$y, labels = labs$label)
I'm quite sure you could work directly on the grobs using clipping functions in grid or gridSVG package.
It's very easy in eulerr R package
library(eulerr)
plot(euler(c("A"=5,"B"=4,"A&B"=2)),quantities = TRUE,fills=c("white","white","red"))
euler set colours
I used package 'VennDiagram' to draw four venn diagram called P1,P2,P3,P4. Then want to grid.arrange to put four graphs on one page.
The code I used is:
P1=draw.pairwise.venn(20,63,6,category = c("blastp", "HMM"), lty =rep("blank",2),fill = c("#9067A7", "#9067A7"), alpha = rep(0.5, 2), cat.pos = c(0,0),cat.dist = rep(0.025, 2),inverted=TRUE)
P2=draw.pairwise.venn(3,242,3,category = c("blastp", "HMM"), lty = rep("blank",2),fill = c("#AB6857", "#AB6857"), alpha = rep(0.5, 2), cat.pos = c(0,0),cat.dist = rep(0.025, 2))
P3=draw.pairwise.venn(7,107,0,category = c("blastp", "HMM"), lty = rep("blank",2),fill = c("#bc767c", "#bc767c"), alpha = rep(0.5, 2), cat.pos = c(0,0),cat.dist = rep(0.025, 2))
P4=draw.pairwise.venn(11,1,0,category = c("blastp", "HMM"), lty = rep("blank",2),fill = c("#628130", "#628130"), alpha = rep(0.5, 2), cat.pos = c(0,0),cat.dist = rep(0.025, 2))
grid.arrange(P1, P2, P3, P4, ncol=2)
But there showed an error:
Error: $ operator is invalid for atomic vectors
When try:
grid.arrange(grid.draw(P1), grid.draw(P2), grid.draw(P3), grid.draw(P4), ncol=2)
Still errors but change to :
only 'grobs' allowed in "gList"
I want to paste these four on one page.
I'am not sure this is related to an update, but I always arrange venndiagrams like:
grid.arrange(grobTree(P1), grobTree(P2), grobTree(P3), grobTree(P4), ncol=2)
You need to convert the venndiagrams to a grid graphical object (grob).