I'm new to rCharts, in fact this is my first attempt. So please forgive a naive question.
I'm trying to create a simple rCharts visual which has a only one horizontal line (X-axis) and no Y-axis. I want to be able to choose the length and each point in the line has mouseover which represents some data. Also I would like to add colors to some of the special points.
This seems very simple, but I'm having great difficulty in this.
library(rCharts)
age <- c(1:2000)
dot <- rep(1,2000)
name <- paste(letters[0], 1:2000, sep="")
df <- data.frame(age=age,dot=dot,name=name)
n1 <- nPlot(dot~age, data=df, type="scatterChart")
n1$chart(tooltipContent = "#! function(key,x,y,e){var d = e.series.values[e.pointIndex];return 'x:'+ x + 'y:' + y + 'name:' + d.name }!#")
n1
Now this will create a line with mouseover but the line in at y=1 and there are x and y axes also. I want just one line, something like a timeline with special events marked.
Thanks a lot.
Well, turning off the y-axis is fairly simple. I added some other ideas to the code.
library(rCharts)
age <- c(1:2000)
dot <- c(
rep(1,1000),
rep(2,1000)
)
name <- c(
rep(letters[1], 1000),
rep(letters[2], 1000)
)
df <- data.frame(age=age,dot=dot,name=name)
n1 <- nPlot(dot~age, data=df, group = "name", type="scatterChart")
n1$chart(
tooltipContent = "#! function(key,x,y,e){
var d = e.series.values[e.pointIndex]
return 'x:'+ x + 'y:' + y + 'name:' + d.name
}!#",
showYAxis = FALSE, #turns off y axis
forceY = c(0,4) #forces y axis to 0 min and 4 max
)
n1
While I think this solves the issue, I am anticipating some things. One is if you define each point, then the data will become large. We could change to lineChart to minimize data sent, but then the tooltip only shows on the points defined. I am sure there is a way to bind an event to the path to show a tooltip then also, but it is beyond my abilities. I would guess you might like the x to be a date format. I'll be happy to demo an example of that also if you would like.
n2 <- nPlot(
dot~age
, data=data.frame(
name = c(rep("A",2),rep("B",2)),
dot = c(1,1,2,2),
age = c(1,1000,1000,2000)
)
, group = "name"
, type="lineChart"
)
n2$chart(
tooltipContent = "#! function(key,x,y,e){
var d = e.series.values[e.pointIndex]
return 'x:'+ x + 'y:' + y + 'name:' + d.name
}!#",
showYAxis = FALSE, #turns off y axis
forceY = c(0,4) #forces y axis to 0 min and 4 max
)
n2
Here is the additional code based on the comments
require(dplyr)
require(magrittr)
require(rCharts)
data <- jsonlite::fromJSON('[
[5,
0, "a1"], [480, 0, "a2"], [250, 0, "a3"], [100, 0, "a4"], [330, 0, "a5"],
[410, 0, "a6"], [475,
0, "a7"], [25, 0, "a8"], [85, 0, "a9"], [220, 0, "a10"],
[600, 0, "a11"]
]') %>% as.data.frame(stringsAsFactors = F) %>%
set_colnames(c("x","y","name")) %>%
mutate(x = as.numeric(x)) %>%
mutate(y = as.numeric(y))
data$grp <- c(rep("A",3),rep("B",5),rep("Z",3))
n1 <- nPlot(
y~x
,group = "grp"
,data = data
,type="scatterChart"
,height=200
)
n1$chart(
tooltipContent = "#! function(key,x,y,e){
var d = e.series.values[e.pointIndex]
var mytip = [];
mytip.push('<h1>name:'+ d.name + '</h1>');
mytip.push('<p>x:' + x + '</p>');
mytip.push('<p>y:' + y + '</p>');
return mytip.join('');
}!#",
showYAxis = FALSE, #turns off y axis
forceY = c(-1,1) #forces y axis to 0 min and 4 max
,showDistX = TRUE #turn on markers on the x axis
,showDistY = FALSE
)
n1$yAxis(
showMaxMin = FALSE
,axisLabel = NULL
)
n1
note: there is a bug in the fisheye that interferes with the tooltip; we can remove to get tooltips to appear immediately
Let me know how this works.
Related
I want to identify 3d cylinders in an rgl plot to obtain one attribute of the nearest / selected cylinder. I tried using labels to simply spell out the attribute, but I work on data with more than 10.000 cylinders. Therefore, it gets so crowded that the labels are unreadable and it takes ages to render.
I tried to understand the documentation of rgl and I guess the solution to my issue is selecting the cylinder in the plot manually. I believe the function selectpoints3d() is probably the way to go. I believe it returns all vertices within the drawn rectangle, but I don't know how to go back to the cylinder data? I could calculate which cylinder is closest to the mean of the selected vertices, but this seems like a "quick & dirty" way to do the job.
Is there a better way to go? I noticed the argument value=FALSE to get the indices only, but I don't know how to go back to the cylinders.
Here is some dummy data and my code:
# dummy data
cylinder <- data.frame(
start_X = rep(1:3, 2)*2,
start_Y = rep(1:2, each = 3)*2,
start_Z = 0,
end_X = rep(1:3, 2)*2 + round(runif(6, -1, 1), 2),
end_Y = rep(1:2, each = 3)*2 + round(runif(6, -1, 1), 2),
end_Z = 0.5,
radius = 0.25,
attribute = sample(letters[1:6], 6)
)
# calculate centers
cylinder$center_X <- rowMeans(cylinder[,c("start_X", "end_X")])
cylinder$center_Y <- rowMeans(cylinder[,c("start_Y", "end_Y")])
cylinder$center_Z <- rowMeans(cylinder[,c("start_Z", "end_Z")])
# create cylinders
cylinder_list <- list()
for (i in 1:nrow(cylinder)) {
cylinder_list[[i]] <- cylinder3d(
center = cbind(
c(cylinder$start_X[i], cylinder$end_X[i]),
c(cylinder$start_Y[i], cylinder$end_Y[i]),
c(cylinder$start_Z[i], cylinder$end_Z[i])),
radius = cylinder$radius[i],
closed = -2)
}
# plot cylinders
open3d()
par3d()
shade3d(shapelist3d(cylinder_list, plot = FALSE), col = "blue")
text3d(cylinder$center_X+0.5, cylinder$center_Y+0.5, cylinder$center_Z+0.5, cylinder$attribute, color="red")
# get attribute
nearby <- selectpoints3d(value=TRUE, button = "right")
nearby <- colMeans(nearby)
cylinder$dist <- sqrt(
(nearby["x"]-cylinder$center_X)**2 +
(nearby["y"]-cylinder$center_Y)**2 +
(nearby["z"]-cylinder$center_Z)**2)
cylinder$attribute[which.min(cylinder$dist)]
If you call selectpoints3d(value = FALSE), you get two columns. The first column is the id of the object that was found. Your cylinders get two ids each. One way to mark the cylinders is to use "tags". For example, this modification of your code:
# dummy data
cylinder <- data.frame(
start_X = rep(1:3, 2)*2,
start_Y = rep(1:2, each = 3)*2,
start_Z = 0,
end_X = rep(1:3, 2)*2 + round(runif(6, -1, 1), 2),
end_Y = rep(1:2, each = 3)*2 + round(runif(6, -1, 1), 2),
end_Z = 0.5,
radius = 0.25,
attribute = sample(letters[1:6], 6)
)
# calculate centers
cylinder$center_X <- rowMeans(cylinder[,c("start_X", "end_X")])
cylinder$center_Y <- rowMeans(cylinder[,c("start_Y", "end_Y")])
cylinder$center_Z <- rowMeans(cylinder[,c("start_Z", "end_Z")])
# create cylinders
cylinder_list <- list()
for (i in 1:nrow(cylinder)) {
cylinder_list[[i]] <- cylinder3d(
center = cbind(
c(cylinder$start_X[i], cylinder$end_X[i]),
c(cylinder$start_Y[i], cylinder$end_Y[i]),
c(cylinder$start_Z[i], cylinder$end_Z[i])),
radius = cylinder$radius[i],
closed = -2)
# Add tag here:
cylinder_list[[i]]$material$tag <- cylinder$attribute[i]
}
# plot cylinders
open3d()
par3d()
shade3d(shapelist3d(cylinder_list, plot = FALSE), col = "blue")
text3d(cylinder$center_X+0.5, cylinder$center_Y+0.5, cylinder$center_Z+0.5, cylinder$attribute, color="red")
# Don't get values, get the ids
nearby <- selectpoints3d(value=FALSE, button = "right", closest = FALSE)
ids <- nearby[, "id"]
# Convert them to tags. If you select one of the labels, you'll get
# a blank in the list of tags, because we didn't tag the text.
unique(tagged3d(id = ids))
When I was trying this, I found that using closest = TRUE in selectpoints3d seemed to get too many ids; there may be a bug there.
I'm attempting to get a r visualization running in PowerBI. It runs fine in R, but for some reason it never finishes loading in PowerBI (no error message, just the timeout screen after 5 minutes). After some experimenting, I've noticed that if I remove one plotly overlay from the create and save widget section, it will load fine. It doesn't matter which one.
I am new to R and powerBi, so any advice on a workaround would be really appreciated.
source('./r_files/flatten_HTML.r')
############### Library Declarations ###############
libraryRequireInstall("ggplot2");
libraryRequireInstall("plotly");
####################################################
################### Actual code ####################
# plot histogram of risk density using monte carlo output
x = Values[,1]; #grab first column of dataframe as dataframe
# create CDF function and overlay onto histogram
cdf = ecdf(x);
# calculate mean cordinates to draw a mean line for selected data
meancordinates = function(xdata) {
v = sum(xdata)
meanxcord = v/length(xdata)
meancord = list(meanxcord = meanxcord, meanycord = cdf(meanxcord))
return(meancord)
};
mean = meancordinates(x);
# calculate median cordinates to draw a median line for selected data
mediancordinates = function(xdata) {
medianxcord = median(xdata)
mediancord = list(medianxcord = medianxcord, medianycord = cdf(medianxcord))
return(mediancord)
};
median = mediancordinates(x)
# calculate the 80% cordinates to draw a 80% line for selected data
eightycordinates = function(xdata) {
eightyxcord = x[which(abs(cdf(xdata)-0.80) == min(abs(cdf(xdata)-0.80)))]
eightycord = list(eightyxcord = eightyxcord, eightyycord = cdf(eightyxcord))
return(eightycord);
}
eighty = eightycordinates(x);
####################################################
############# Create and save widget ###############
p = plot_ly(x = x, type = "histogram", histnorm = "probability density", name = "Histogram")
p = p %>% add_segments(
x = median$medianxcord, xend = median$medianxcord,
y = 0, yend = median$medianycord,
name = "Median")
p = p %>% add_segments(
x = eighty$eightyxcord, xend = eighty$eightyxcord,
y = 0, yend = eighty$eightyycord,
name = "80%")
p = p %>% add_segments(
x = mean$meanxcord, xend = mean$meanxcord,
y = 0, yend = mean$meanycord,
name = "Mean")
p = p %>% add_lines(x = x, y = cdf(x), name = "CDF");
internalSaveWidget(p, 'out.html');
####################################################
I get 0 values on the y Axis while plotting a discreteBarChart inside renderChart(), However, the highest value of yAxis appears (not 0) but also with some wierd format and commmas (see 2nd screenshot down named Chart Plot)
I want to plot 2 columns in rCharts, the x Axis is a character (countryname) and the yAxis is numeric (Collective_Turnover)
I created this variable (Collective_Turnover) from the data, it is the sum of the Net_Turnover
I tried to put as.numeric() before it, but still, getting 0 on the yAxis
data$countryname= as.character(data$countryname)
output$top10countries <-renderChart({
topcountries <-
arrange(data%>%
group_by(as.character(countryname)) %>%
summarise(
Collective_Turnover= sum(as.numeric(`Net turnover`))
), desc(Collective_Turnover))
colnames(topcountries )[colnames(topcountries )=="as.character(countryname)"] <- "Country"
topcountries <- subset(topcountries [1:10,], select = c(Country, Collective_Turnover))
p <- nPlot(Collective_Turnover~Country, data = topcountries , type = "discreteBarChart", dom = "top10countries")
p$params$width <- 1000
p$params$height <- 200
p$xAxis(staggerLabels = TRUE)
# p$yAxis(axisLabel = "CollectiveTO", width = 50)
return(p)
})
The output of topcountries in R is a table like this:
that is arranged in descending order...
and the plot that i get is this:
The ticks labels are truncated because they are too long. You need to set the left margin and a padding. To get rid of the commas, use a number formatter.
dat <- data.frame(
Country = c("Russian", "Italy", "Spain"),
x = c(12748613.6, 5432101.2, 205789.7)
)
p <- nPlot(x ~ Country, data = dat, type = "discreteBarChart")
p$yAxis(tickPadding = 15, tickFormat = "#! function(d) {return d3.format('.1')(d)} !#")
p$chart(margin = list(left = 100))
p
We are trying to plot around 4000 data points from column a1 as bars using Highcharts. The colors of the a1 bars are based on the values of another column called a3. If a3 is negative on one row, the corresponding bar about a1 should be red, and positive a3 should give color green.
The problem is that the graph takes around 25 seconds to generate, and it takes 20 seconds just to print the graph. Could someone help us fix the code and make it faster? We tried to disable animations and shadows, but that did not help too much. Here is the code:
fun <- function(){
## Generate a random data set with roughly 4,000 lines
df <- as.data.frame(cbind(x = seq(1:3900),
a1 = rnorm(3900, 1000000, 2000000),
a2 = abs(rnorm(3900, 1000000, 2000000)),
a3 = rnorm(3900, 20000, 30000),
a4 = rnorm(3900, 1000, 500),
a5 = rnorm(3900, 0.01, 0.02)))
## Modify the data set to assign colors to each bar based on the values
## of a3. Green bars signify positive a3's and red bars signify
## negative a3's
df <- df %>%
mutate(a6 = cumsum(a3)) %>%
mutate(color = ifelse(a3 > 0,
"rgba(50,205,50,0.6)",
"rgba(223,83,83,0.6)")) %>%
mutate(y = a1,
a1 = comma_format()(round(a1, 0)),
a3 = comma_format()(round(a3, 0)),
a4 = comma_format()(round(a4, 4)),
a5 = comma_format()(round(a5, 0)),
a6 = comma_format()(round(a6, 0))
)
## Store the data in a list so that it is readable by Highcharts
input <- list()
input <- lapply(unname(split(df, seq(nrow(df)))), as.list)
## Draw the graph with Highcharts
a <- rCharts::Highcharts$new()
a$series(data = input,
name = "a1 values",
type = "column")
a$plotOptions(series = list(turboThreshold = 4000))
a$chart(zoomType = "xy", animation = FALSE)
a$addParams(width = 1000, height = 400, title = list(text = "The Slow Chart"))
a$tooltip(formatter = "#! function()
{return 'Date:<b> ' + this.point.x +
'</b> <br/>a1 values:<b> ' + this.point.a1 +
'</b> <br/>a3 values:<b> ' + this.point.a2 +
'</b> <br/>a4 values:<b> ' + this.point.a3 +
'</b> <br/>a5 values:<b> ' + this.point.a5 +
'</b> <br/>a6 values:<b> ' + this.point.a6} !#")
print(a)
}
Any help is appreciated!
First of all, please show what packages are you using in your code (dplyr, scales).
There's a boost module for highcharts. sadly rCharts dont include that module by default so you need to add manually.
By other hand. There is a new wrapper for highcharts called highcharter which have an implementation of this module. Using it dont take more than 1 second to chart the 3900 columns.
highchart2() %>%
hc_title(text = "Not so slow chart ;)") %>%
hc_subtitle(text = "Thanks boost module") %>%
hc_chart(zoomType = "x", animation = FALSE, type = "column") %>%
hc_plotOptions(series = list(turboThreshold = 4000)) %>%
hc_add_serie(data = input)
Check the speed/here:
http://rpubs.com/jbkunst/highcharts-too-slow-when-plotting-4000-bars-rcharts
The file to generate the graph can be downloaded from https://db.tt/hHYq0mSA. I'm sharing a link because dput generates a huge output. This is what I'm runing
require(rCharts)
dense<-readRDS("dense.RDS")
nPlot(x = "minutes", y = "FBS", data = dense, type = "lineChart")
This is what I get
What are the numbers (63382626 and 67270968) in the Y axis? how can I make them go away?
Thanks!
The strange digits are the final digits of the min and max of y
> options(digits=12)
> min(dense[,2])
[1] 0.000239026338263
> max(dense[,2])
[1] 0.0417486727097
You need to add some formatting rules on the y axis ticks:
require(rCharts)
dense<-readRDS("dense.RDS")
n1 <- nPlot(x = "minutes", y = "FBS", data = dense, type = "lineChart")
n1$yAxis(tickFormat = "#! function(d) {return d3.format(',.2f')(d)} !#")
n1
Aternative you can set the domain of the yaxis and keep the digits
require(rCharts)
dense<-readRDS("../Downloads/dense.RDS")
n1 <- nPlot(x = "minutes", y = "FBS", data = dense, type = "lineChart")
n1$chart(forceY = c(0, 0.05))
n1