r अलग-अलग अंतराल चौड़ाई के साथ असतत रंग बार बनाएं और किंवदंती के स्तर के बीच कोई रिक्ति नहीं




ggplot2 colors (3)

मैं ggplot2 में इस रंग पैमाने को पुन: उत्पन्न करना चाहता ggplot2 : ( Source )

अतीत में मैंने found कि ggplot2 में लेबल के बीच असतत रंग तराजू ggplot2 मुश्किल हो सकता है।

क्या इसे पूरा किया जा सकता है? एक समान, लेकिन पूरी तरह से समान प्रश्न जो मैंने हाल ही में पेश किया है वह this है।


तुम कोशिश कर सकते हो। पहले जवाब के लिए here भी देखें

# data
set.seed(1324)
dat <- data.frame(x=0:100, y=runif(101, 0, 10), z=seq(0, 12, len=101))
# add discrete values
dat$col <- cut(include.lowest = T,
  dat$z, 
  breaks=c(0, 2, 4, 6, 8, max(dat$z)), 
  labels=c(2, 4, 6, 8, 10)
)
# Discete
ggplot(dat, aes(x,y,fill=col)) + 
  geom_point(aes(col=col),size=8, show.legend = F) +   
  geom_col(alpha=0)+
  scale_fill_brewer("", palette = "Reds")+
  scale_colour_brewer("", palette="Reds")+
  scale_alpha_discrete(range=c(0,1))+
  guides(fill = guide_legend(nrow=1,override.aes = list(alpha = 1), 
                             label.position="bottom",
                             label.hjust = -0.05)) +
  theme(legend.position="bottom",
        legend.key.width = unit(3, "cm"), 
        legend.key.height = unit(1, "cm"))

# Continuous
ggplot(dat, aes(x,y,color=y)) + 
  geom_point(size=8) +   
  scale_colour_continuous("",limits=c(0,10), 
                          breaks=c(0, 2, 4, 6, 8, 10),low = "white", high = "red")+
  theme(legend.position="bottom",
        legend.key.width = unit(3, "cm"), 
        legend.key.height = unit(1, "cm"))


Tjebo के जवाब के लिए धन्यवाद, मैं एक ऐसा फंक्शन बनाने में कामयाब रहा, जिसमें एक अच्छा colorbar प्लॉट किया गया cowplot , उसके उदाहरण में cowplot , patchwork या इसी तरह के अन्य पैकेजों का उपयोग करके प्लॉट्स में जोड़ा गया था।

यहां यह है: EDIT: आप इसे github पर भी पा सकते हैं

plot_discrete_cbar = function(
    breaks, # Vector of breaks. If +-Inf are used, triangles will be added to the sides of the color bar
    palette = "Greys", # RColorBrewer palette to use
    colors = RColorBrewer::brewer.pal(length(breaks) - 1, palette), # Alternatively, manually set colors
    direction = 1, # Flip colors? Can be 1 or -1
    spacing = "natural", # Spacing between labels. Can be "natural" or "constant"
    border_color = NA, # NA = no border color
    legend_title = NULL,
    legend_direction = "horizontal", # Can be "horizontal" or "vertical"
    font_size = 5,
    expand_size = 1, # Controls spacing around legend plot
    spacing_scaling = 1, # Multiplicative factor for label and legend title spacing
    width = 0.1, # Thickness of color bar
    triangle_size = 0.1 # Relative width of +-Inf triangles
) {
    require(ggplot2)
    if (!(spacing %in% c("natural", "constant"))) stop("spacing must be either 'natural' or 'constant'")
    if (!(direction %in% c(1, -1))) stop("direction must be either 1 or -1")
    if (!(legend_direction %in% c("horizontal", "vertical"))) stop("legend_direction must be either 'horizontal' or 'vertical'")
    breaks = as.numeric(breaks)
    new_breaks = sort(unique(breaks))
    if (any(new_breaks != breaks)) warning("Wrong order or duplicated breaks")
    breaks = new_breaks
    if (class(colors) == "function") colors = colors(length(breaks) - 1)
    if (length(colors) != length(breaks) - 1) stop("Number of colors (", length(colors), ") must be equal to number of breaks (", length(breaks), ") minus 1")
    if (!missing(colors)) warning("Ignoring RColorBrewer palette '", palette, "', since colors were passed manually")

    if (direction == -1) colors = rev(colors)

    inf_breaks = which(is.infinite(breaks))
    if (length(inf_breaks) != 0) breaks = breaks[-inf_breaks]
    plotcolors = colors

    n_breaks = length(breaks)

    labels = breaks

    if (spacing == "constant") {
        breaks = 1:n_breaks
    }

    r_breaks = range(breaks)

    cbar_df = data.frame(stringsAsFactors = FALSE,
        y = breaks,
        yend = c(breaks[-1], NA),
        color = as.character(1:n_breaks)
    )[-n_breaks,]

    xmin = 1 - width/2
    xmax = 1 + width/2

    cbar_plot = ggplot(cbar_df, aes(xmin=xmin, xmax = xmax, ymin = y, ymax = yend, fill = factor(color, levels = 1:length(colors)))) +
        geom_rect(show.legend = FALSE,
                  color=border_color)

    if (any(inf_breaks == 1)) { # Add < arrow for -Inf
        firstv = breaks[1]
        polystart = data.frame(
            x = c(xmin, xmax, 1),
            y = c(rep(firstv, 2), firstv - diff(r_breaks) * triangle_size)
        )
        plotcolors = plotcolors[-1]
        cbar_plot = cbar_plot +
            geom_polygon(data=polystart, aes(x=x, y=y),
                        show.legend = FALSE,
                        inherit.aes = FALSE,
                        fill = colors[1],
                        color=border_color)
    }
    if (any(inf_breaks > 1)) { # Add > arrow for +Inf
        lastv = breaks[n_breaks]
        polyend = data.frame(
            x = c(xmin, xmax, 1),
            y = c(rep(lastv, 2), lastv + diff(r_breaks) * triangle_size)
        )
        plotcolors = plotcolors[-length(plotcolors)]
        cbar_plot = cbar_plot +
            geom_polygon(data=polyend, aes(x=x, y=y),
                        show.legend = FALSE,
                        inherit.aes = FALSE,
                        fill = colors[length(colors)],
                        color=border_color)
    }

    if (legend_direction == "horizontal") { #horizontal legend
        mul = 1
        x = xmin
        xend = xmax
        cbar_plot = cbar_plot + coord_flip()
        angle = 0
        legend_position = xmax + 0.1 * spacing_scaling
    } else { # vertical legend
        mul = -1
        x = xmax
        xend = xmin
        angle = -90
        legend_position = xmax + 0.2 * spacing_scaling
    }

    cbar_plot = cbar_plot +
        geom_segment(data=data.frame(y = breaks, yend = breaks),
            aes(y=y, yend=yend),
            x = x - 0.05 * mul * spacing_scaling, xend = xend,
            inherit.aes = FALSE) +
        annotate(geom = 'text', x = x - 0.1 * mul * spacing_scaling, y = breaks,
                label = labels,
                size = font_size) +
        scale_x_continuous(expand = c(expand_size,expand_size)) +
        scale_fill_manual(values=plotcolors) +
        theme_void()

    if (!is.null(legend_title)) { # Add legend title
        cbar_plot = cbar_plot +
            annotate(geom = 'text', x = legend_position, y = mean(r_breaks),
                label = legend_title,
                angle = angle,
                size = font_size)
    }

    cbar_plot
}

उदाहरण का उपयोग:

plot_discrete_cbar(c(1:10))

plot_discrete_cbar(c(0,2,5,10,20, Inf), palette="Reds")

plot_discrete_cbar(c(0,2,5,10,20, Inf), colors=rainbow, legend_direction="vertical", legend_title="A title! WOW!", border_color="red")

plot_discrete_cbar(c(-Inf, -8, -4, -2, -1, 1, 2, 4, 8, Inf), palette="BrBG", legend_title="Precipitation bias (mm/day)")

plot_discrete_cbar(c(-Inf, -8, -4, -2, -1, 1, 2, 4, 8, Inf), palette="BrBG", legend_title="Precipitation bias (mm/day)", spacing="constant")


इस सवाल में @ हेनरिक के जवाब से प्रेरित होकर, एक संभावित समाधान एक ऐसा प्लॉट बनाना है जो एक किंवदंती की तरह दिखता है :)

require(ggplot2)
require(cowplot)


values <- c(0,1,2,5,10) # this vector is needed not only for the data frame cbar, but also for plotting
group <- letters[1:5]
diff_values <- c(0, diff(values))
cbar_df <- data.frame(x = 1, y = values, diff_values,group,  stringsAsFactors = FALSE)
#that's for the fake legend

iris2 <- iris #don't want to mess with your iris data set
              #I used iris because you hadn't provided data
iris2$cuts <- cut(iris2$Petal.Length, values) #the already offered 'cut-approach' 


p1  <- ggplot(iris2, aes(Sepal.Length, y = Sepal.Width, color = cuts))+ 
          geom_point() +
          scale_color_brewer("", palette = "Reds")

cbar_plot <- ggplot(cbar_df, aes(x, y = diff_values, fill = c(NA, rev(group[2:5])))) + 
  # I had to do implement this 'fill=' workaround 
  # in creating a new vector introducing an NA, 
  # and I had to flip the fills in order to fit to the scale... 
    geom_col(width = 0.1, show.legend = FALSE)  +
    geom_segment(y = values, yend = values, x = 0.9, xend = 1.05) +
    annotate(geom = 'text', x = 0.85, y = values, label = values) +
  # the numbers are quasi-randomly chosen but define the length of your ticks, obviously
    scale_x_continuous(expand = c(1,1)) + 
  # you might need to play around with the expand argument for the width of your legend
    scale_fill_brewer("", palette = "Reds", direction = -1) +  
  # don't know why you have to flip this again... 
    coord_flip() +
    theme_void()

plot_grid(p1, cbar_plot, nrow = 2)

मेरा मतलब है - निश्चित रूप से सुधार के लिए बहुत जगह है (किंवदंती की साजिश को छोटा करना आदि ...)। लेकिन आप क्या सोचते हैं?

#P.S. 
sessionInfo() 
cowplot_0.9.2 ggplot2_2.2.1




colors