How to manually create line types in ggplot?
You can specify how long you would like your on- and off-lines to be by providing your geom function with a hex string. From the docs:
# An example with hex strings, the string "33" specifies three units on followed
# by three off and "3313" specifies three units on followed by three off followed
# by one on and finally three off.
f + geom_line(linetype = "3313")
R multiple lines plotly chart with customized line types
At least for the line types (dash vs line), you can you 'linetype':
library(dplyr)
library(plotly)
df = data.frame(xVals = rep(1:10,2),
yVals = c(1:10, 2:11),
myColor = c(rep('Red', 10), rep('Blue', 10)),
myType = c(rep('solid', 10), rep('dot', 10)),
myName = c(rep('FirstName', 10), rep('SecondName', 10)))
plot_ly(df,
x = ~xVals,
y = ~yVals,
color = ~I(myColor),
name = ~myName,
type = 'scatter',
mode = 'lines',
linetype = ~I(myType)
)
Create a line chart with different type of linetypes based on one or more dropdown selections
One of the first problem is in the following statement
colnames(addedDf) <- c("x", "y", "x1", "y1", "x2", "y2")[1:ncol(addedDf)]
As it only allows you to assign x and y as the names regardless of what you select; Sell Out, Gross Sales or Gross Profit. I have now updated the code for the remaining issues in a long form.
library(shiny)
library(shinydashboard)
library(plotly)
library(tidyr)
library(dplyr)
library(DT)
BRAND<-c("CHOKIS","CHOKIS","CHOKIS","CHOKIS","CHOKIS","CHOKIS","LARA CHOCO CHIPS","LARA CHOCO CHIPS","LARA CHOCO CHIPS")
BRAND_COLOR<-c("#8050f0","#8050f0","#8050f0","#8050f0","#8050f0","#8050f0","#f050c0","#f050c0","#f050c0")
SellOut.x<-c(23,34,56,77,78,34,34,64,76)
SellOut.y<-c(43,54,76,78,87,98,76,76,56)
GrossProfit.x1<-c(23,34,56,75,78,34,34,64,76)
GrossProfit.y1<-c(33,54,76,76,87,98,76,76,56)
GrossSales.x2<-c(53,34,56,77,78,34,34,84,76)
GrossSales.y2<-c(63,54,76,78,87,98,76,76,86)
r<-c(58,46,76,76,54,21,69,98,98)
mt <- c('Sell Out','Gross Sales','Gross Profit')
graph1.data<-data.frame(BRAND,BRAND_COLOR,r)
dfc <- data.frame(series=c(0,1,2), lines=c("solid","dashed","dotted"))
# data frame containing columns to be added
df6 <- data.frame(SellOut.x, SellOut.y, GrossProfit.x1, GrossProfit.y1, GrossSales.x2, GrossSales.y2)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
selectInput("metric","Metric",c('Gross Sales','Gross Profit','Sell Out'),multiple = T,selected = "Sell Out")
),
dashboardBody(
DTOutput("df"),
plotlyOutput("plot")
)
)
server <- function(input, output) {
choices <- reactive({
c3 <- gsub(" ", "", input$metric) # remove space
return(c3)
})
mydata <- eventReactive(input$metric, {
if(length(choices()) > 0){
g1 <- apply(sapply(X = choices(), FUN = grepl, colnames(df6)), MARGIN = 1, FUN = any)
addedDf <- df6[, g1] # columns to be added
ab <- colnames(addedDf)
colnames(addedDf) <- sapply(strsplit(ab,split="\\."),"[")[2,]
combinedDf <- cbind(graph1.data, addedDf)
abc <- colnames(combinedDf)
if (sum(as.character(abc) %in% c("x", "y"))>0) { df1 <- combinedDf %>% rename(x0=x,y0=y)
}else df1 <- combinedDf
#mt <- c('Sell Out','Gross Sales','Gross Profit')
mydf <- df1 %>% # rename(x0=x,y0=y) %>%
dplyr::mutate(row = 1:n(),r=r) %>%
pivot_longer(cols = -c(row,BRAND,BRAND_COLOR,r)) %>%
separate(col = name, into = c("var", "series"), sep = 1) %>%
pivot_wider(id_cols = c(BRAND,BRAND_COLOR,r,row, series), names_from = "var", values_from = "value") %>%
dplyr::mutate(metric=ifelse(series==0,mt[1],ifelse(series==1,mt[3],mt[2]))) %>%
dplyr::mutate(label=ifelse(series==0,paste(BRAND,mt[1]),ifelse(series==1,paste(BRAND,mt[3]),paste(BRAND,mt[2])))) %>% print(n=Inf)
}else {mydf <- graph1.data}
mydf
}, ignoreNULL = FALSE)
output$df <- renderDT({
mydata()
})
myplot <- reactive({
req(mydata(),input$metric)
brand.colors <- mydata()$BRAND_COLOR
names(brand.colors) <- mydata()$label
linetype <- dfc$lines[dfc$series %in% unique(mydata()$series)]
print(linetype)
if(length(input$metric) == 1) {
p <- mydata() %>% ggplot2::ggplot(aes(x, y, color = label))
}else {
p <- mydata() %>% ggplot2::ggplot(aes(x, y, group=metric, color = label))
}
p <- p + ggplot2::geom_line(aes(x, linetype=series)) + ##
# warnings suppressed on text property
suppressWarnings(ggplot2::geom_point(aes(x, y, size = r), show.legend = TRUE)) +
ggplot2::scale_color_manual(values = brand.colors) +
scale_linetype_manual(name="", breaks=mydata()$series, values = linetype)
p
})
output$plot <- renderPlotly({
req(myplot())
ggplotly(myplot())
})
}
shinyApp(ui, server)
Change line type for certain categories in ggplot?
This could be achieved as follows:
- Arrange your df by cat in descending order so that A and B come last
- Map the condition
cat %in% c("A", "B")
on linetype - Set the linetypes for TRUE and FALSE using
scale_linetype_manual
- get rid of the linetype legend using
guides
library(reshape2)
library(ggplot2)
df = data.frame(cat = LETTERS[1:6], VAR1 = runif(6), VAR2 = runif(6), VAR3 = runif(6), VAR4 = runif(6))
df_melted = melt(df, id.vars = 'cat')
df_melted <- arrange(df_melted, desc(cat))
#> Error in arrange(df_melted, desc(cat)): could not find function "arrange"
ggplot(df_melted, aes(x = variable, y = value)) +
geom_line(aes(color = cat, group = cat, linetype = cat %in% c("A", "B"))) +
scale_linetype_manual(values = c("TRUE" = "solid", "FALSE" = "dotted")) +
guides(linetype = FALSE)
EDIT An alternative approach to achieve your result may look like so. Here I also use the same pattern to adjust the size. What I like about this approach is that we don't need a condition and we only have one legend:
library(reshape2)
library(ggplot2)
library(dplyr)
df = data.frame(cat = LETTERS[1:6], VAR1 = runif(6), VAR2 = runif(6), VAR3 = runif(6), VAR4 = runif(6))
df_melted = melt(df, id.vars = 'cat')
df_melted <- arrange(df_melted, desc(cat))
ggplot(df_melted, aes(x = variable, y = value, group = cat)) +
geom_line(aes(color = cat, linetype = cat, size = cat)) +
scale_linetype_manual(values = c(A = "solid", B = "solid", rep("dotted", 4))) +
scale_size_manual(values = c(A = 1, B = 1, rep(.5, 4)))
More variation in line types in R (add dots, plusses...)
You could do it by utilising predict
to break up the abline
into segments, that you can then specify a pch=
against. By manually specifying points, you can decide how often you want a custom tick mark in the length.out=
argument:
x <- 1:10
y <- jitter(x,5)
fit <- lm(y~x)
plot(x,y)
pts <- seq(min(x),max(x),length.out=10)
lines(pts, predict(fit, list(x=pts)), type="o", pch="^")
ggplot2 - control linetypes when more than one line
ggplot(dsamp, aes(x=x)) +
geom_line(aes(y=y, linetype="Simple Model"),size=1.5) +
geom_line(aes(y=z, linetype="Complex Model"),size=1.5)+
scale_linetype_manual(values=c(5,1))
The above code will give you a plot where both lines look similar in the legend.
This is because linetype=5
is equivalent to "longdash" (2 is "dashed"). The longdashes are too long to show in the legend.
If you want to retain the size=1.5
(or higher) with the longdashes and have a proper legend you will need to also change the size of the legend, for example with:
+theme(legend.key.size=unit(2,"cm"))
Related Topics
R: How to Rbind Two Huge Data-Frames Without Running Out of Memory
Imported a CSV-Dataset to R But the Values Becomes Factors
Create an Id (Row Number) Column
Apply a Function to a Subset of Data.Table Columns, by Column-Indices Instead of Name
Only Download Sources of a Package and All Dependencies
How to 'Source()' and Continue After an Error
Suggestions for Speeding Up Random Forests
Create a Vector of All Days Between Two Dates
Test If an Argument of a Function Is Set or Not in R
Selecting Columns in R Data Frame Based on Those *Not* in a Vector
When Should I Use Setdt() Instead of Data.Table() to Create a Data.Table
Superscript and Subscript Axis Labels in Ggplot2
Standard Error Bars Using Stat_Summary
R Interpolated Polar Contour Plot
Identifying Dependencies of R Functions and Scripts
Density2D Plot Using Another Variable for the Fill (Similar to Geom_Tile)