简体   繁体   中英

ggplot2 bar chart tick position and custom legend issue

I have a ggplo bar chart like this

条形图

created from

library(lubridate)
library(ggplot2)
library(grid)
library(scales)

### Set up dummy data.
dayVec     <- seq(ymd('2016-01-01'), ymd('2016-01-10'), by = '1 day')
dayCount   <- length(dayVec)
dayValVec1 <- c(0,-0.25,0.15,0.3,0.4,0.10,0.17,0.22,0.50,0.89)
dayValVec2 <- c(0.15,0.2,-0.17,0.6,0.16,0.41,0.55,0.80,0.90,1.00)
dayValVec3 <- dayValVec2
dayDF      <- data.frame(Date = rep(dayVec, 3),
                     DataType = factor(c(rep('A', dayCount), rep('B',     dayCount), rep('C', dayCount))),
                     Value = c(dayValVec1, dayValVec2, dayValVec3))

p <- ggplot(dayDF,aes(Date, Value, colour = DataType)) +
theme_bw() +
ggtitle("Chart Title \n") +
scale_color_manual("",values = c("#033563", "#E1E2D2"),labels = c("xxx ", "yyy     ")) +
geom_rect(aes(xmin = ymd(min(dayDF$Date)), 
            xmax = ymd('2016-01-06'),
            ymin = -Inf,
            ymax = Inf
), fill = "#E1E2D2", alpha = 0.1, colour = "#E1E2D2") +
geom_bar(stat = "identity", fill = "#033563", colour = "#033563") +
geom_hline(yintercept = 0, size = 1) +
scale_x_datetime(expand = c(0,0), labels = date_format('%b-%d'), breaks =  date_breaks('1 day')) +
scale_y_continuous(expand = c(0,0), labels = percent, limits =  c(min(dayDF$Value)*1.2, max(dayDF$Value)*1.2)) +
theme(axis.text.x  = element_text(angle = 90), 
    axis.title.x = element_blank(), 
    axis.title.y = element_blank(),
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_line(size = 0.5, colour = "black"),
    axis.line  = element_line(size = 1),
    axis.ticks = element_line(size = 1),
    axis.text  = element_text(size = 20, colour = "#033563"),
    axis.title.x = element_text(hjust = 2),
    plot.title = element_text(size = 40, face = "bold", colour = "#033563"),
    legend.position = 'bottom',
    legend.text = element_text(colour = "#033563", size = 20),
    legend.key  = element_blank(),
    panel.border = element_rect(colour = "black", fill = NA, size = 1.5)
)
p

I have to problems now, first I want to have the goem_rect to start at 0 not centered at the first bar, the problem here seems to be the date x-axis. And secondly I would like to have a legend like this

传说

at the bottom of the chart. I tried creating a dummy data series to get two legend entries, but it doesn't even show the legend. I would prefer if the legend could be manipulated without messing with the data. The 'yyy' legend entry should indicate what the shaded are represents. Thanks in advance, I am quite a newbie to ggplot2.

Here is a solution :

最终情节

  1. 1st problem with geom_rect() due to format.

I prefered POSIXct , so I could easily modify the x axis :

geom_rect(aes(xmin = as.POSIXct("2015-12-31 12:00:00"), 
        xmax = as.POSIXct("2016-01-06 12:00:00"),
        ymin = -Inf,
        ymax = Inf, 
        fill = "#E1E2D2"),
        color = "#E1E2D2", alpha = 0.1)

Tip : Start the "2015-12-31 12:00:00" to expand the geom_rect() and end the "2016-01-06 12:00:00" if you want to totaly fill the Jan 06.


  1. Legend

You should use scale_fill_manual() instead of scale_color_manual()
And you have to put the fill argument inside aes for geom_rect() and geom_bar() .


Code:

library(lubridate)
library(ggplot2)
library(grid)
library(scales)

dayVec     <- seq(as.POSIXct('2016-01-01'), as.POSIXct('2016-01-10'), by = '1 day')
dayCount   <- length(dayVec)
dayValVec1 <- c(0,-0.25,0.15,0.3,0.4,0.10,0.17,0.22,0.50,0.89)
dayValVec2 <- c(0.15,0.2,-0.17,0.6,0.16,0.41,0.55,0.80,0.90,1.00)
dayValVec3 <- dayValVec2
dayDF      <- data.frame(Date = rep(dayVec, 3),
                 DataType = factor(c(rep('A', dayCount), rep('B',     dayCount), rep('C', dayCount))),
                 Value = c(dayValVec1, dayValVec2, dayValVec3))
dayDF$Date = as.POSIXct(dayDF$Date)

p <- ggplot(dayDF,aes(Date, Value, colour = DataType)) +
theme_bw() +
ggtitle("Chart Title \n") +
geom_rect(aes(xmin = as.POSIXct("2015-12-31 12:00:00"), 
        xmax = as.POSIXct("2016-01-06 12:00:00"),
        ymin = -Inf,
        ymax = Inf, 
        fill = "#E1E2D2"),
        color = "#E1E2D2", alpha = 0.1) +
geom_bar(aes(fill = "#033563"), color = "#033563", stat = "identity") +
geom_hline(yintercept = 0, size = 1) +
scale_x_datetime(expand = c(0,0), labels = date_format('%b-%d'), breaks =  date_breaks('1 day')) +
scale_y_continuous(expand = c(0,0), labels = percent, limits =  c(min(dayDF$Value)*1.2, max(dayDF$Value)*1.2)) +
theme(axis.text.x  = element_text(angle = 90), 
axis.title.x = element_blank(), 
axis.title.y = element_blank(),
panel.grid.minor = element_blank(),
panel.grid.major.x = element_blank(),
panel.grid.major.y = element_line(size = 0.5, color = "black"),
axis.line  = element_line(size = 1),
axis.ticks = element_line(size = 1),
axis.text  = element_text(size = 20, color = "#033563"),
axis.title.x = element_text(hjust = 2),
plot.title = element_text(size = 40, face = "bold", colour = "#033563"),
legend.position = 'bottom',
legend.text = element_text(color = "#033563", size = 20),
legend.key  = element_blank(),
panel.border = element_rect(color = "black", fill = NA, size = 1.5)
) +
scale_fill_manual("",values = c("#033563", "#E1E2D2"),labels = c("xxx ", "yyy "))
p

PS : I had to specify tz = "Europe/Paris" in scale_x_datetime(label = date_format()) to have correct dates, depending on location.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM