I've generated a vector of hex colour codes using colorfindr.
I would like to sort them by colour from light to dark.
A quick search has revealed that this is not a simple issue, for example: https://www.alanzucconi.com/2015/09/30/colour-sorting/ or https://mathematica.stackexchange.com/questions/87588/how-to-sort-colors-properly
The colour vector I am working with is:
my_colours <- c("#F6F5F5", "#F4F3F0", "#EDF2F0", "#E1E2E3", "#C2D3DD", "#F6F1E5",
"#404965", "#E4CCD0", "#DFC575", "#D14845", "#E8B426", "#DF7B6D",
"#8DBAD3", "#C44334", "#DE7E31", "#BCBFCD", "#9E4049", "#97372F",
"#BC9AB0", "#4E3427", "#132021", "#0273AD", "#1D3F59", "#F9E892",
"#E2A4AF", "#F6E8D3", "#A5B774", "#A38074", "#6B847E", "#61ABCC",
"#6F86AC", "#B2BC3D", "#718E43", "#077A85", "#28A8C4", "#1D7B51",
"#A57D35", "#3483B0", "#F7CA0E", "#F9CE73", "#FDE35C", "#FAE214",
"#F4DDD2", "#F4C8BE", "#F5BD87", "#F3B61E", "#F2A581", "#F38387",
"#F3A72F", "#F3952F")
Which looks like this:
I have tried niavely sorting the hex colour codes in {my_colours} but this does not really improve the order.
Any pointers or guidance to address this query in the context of R would be most welcome.
To "sort" color in a pleasing way where similar colors are grouped together, we can try to do find the shortest path that connects all colors in a color space. This turns out to be the same as the famous traveling salesman problem. Here's a quick way to do this is in R using the RGB color space:
# original colors
ggplot2::qplot(x = 1:50, y = 1, fill = I(my_colours), geom = 'col', width = 1) + ggplot2::theme_void()
library(TSP)
rgb <- col2rgb(my_colours)
tsp <- as.TSP(dist(t(rgb)))
sol <- solve_TSP(tsp, control = list(repetitions = 1e3))
ordered_cols <- my_colours[sol]
ggplot2::qplot(x = 1:50, y = 1, fill = I(ordered_cols), geom = 'col', width = 1) + ggplot2::theme_void()
You can use different color spaces to get different results.
Edit:
Sorting from light to dark is much easier, just use Lab space:
lab <- convertColor(t(rgb), 'sRGB', 'Lab')
ordered_cols2 <- my_colours[order(lab[, 'L'])]
ggplot2::qplot(x = 1:50, y = 1, fill = I(ordered_cols2), geom = 'col', width = 1) + ggplot2::theme_void()
Related
I'm creating a tree with a ggtree and gheatmap. I am trying to work out how to remove the space between the tip tiles and/or merge adjacent tiles with the same value.
Below is the code I used:
library(ape)
library(tidyverse)
library(ggtree)
tree <- rtree(50)
tree_plot <- ggtree(tree, size = 1, layout = "circular", branch.length = "none")
dummy_data <- data.frame(data = c(rep(1,10),rep(2,10),rep(3,10), rep(4,10), rep(5,10)))
row.names(dummy_data) <- tree$tip.label
gheat_Sensitivity <- gheatmap(p = tree_plot, data=dummy_data, width=0.1, colnames = FALSE) +
new_scale(aes(color = dummy_data)) +
scale_fill_gradientn(colors = c("grey", "yellow"), breaks = c(1, 5.0))
plot(gheat_Sensitivity)
This creates the tree I am after:
ggtree plot
However I would like to remove the spacing between the heatmap tiles so that there is a continuous look to it. Specifically, I would like adjacent tiles with the same value to look like one larger tile.
Any help would be very appreciated,
Cheers,
Tom
Bit late, but for anyone else who has the same issue, you can add colour=NA to the gheatmap call, i.e.
gheatmap(p = tree_plot, data=dummy_data, width=0.1, colnames = FALSE, color=NA)
See here - heatmap with the left with the row space, right after using color=NA.
I am trying to make a map with hotels in las vegas. I have all the coordinates. I also made a map with a dot at the 'hotel points'. But these dots are all black. I need every hotel (dot) to be another color.
As you can see, all the dots (hotels) are black..
This is my code:
df_hotels <- df_joinall %>%
group_by(hotel_name)
df <- st_as_sf(df_hotels, coords = c("Longitude","Latitude"))
tmap_mode("view")+
tm_basemap("OpenStreetMap") +
tm_shape(df) +
tm_dots(popup.format = list(text.align = "center"), size = 0.5, alpha = 0.7)
Does anyone has suggestions on how to give every point (hotel) another color
To have the points colored you need to map the col aesthetic to a column of your data frame. Note that {tmap} requires column names enclosed in quotation marks.
Your example is not exactly reproducible, but I expect this to work:
df_hotels <- df_joinall %>%
group_by(hotel_name)
df <- st_as_sf(df_hotels, coords = c("Longitude","Latitude"))
tmap_mode("view")+
tm_basemap("OpenStreetMap") +
tm_shape(df) + tm_dots(col = "hotel_name", size = 0.5, alpha = 0.7)
How can I show the dots colored using the mosaic package to do a dotplot?
library(mosaic)
n=500
r =rnorm(n)
d = data.frame( x = sample(r ,n= 1,size = n, replace = TRUE), color = c(rep("red",n/2), rep("green",n/2)))
dotPlot(d$x,breaks = seq(min(d$x)-.1,max(d$x)+.1,.1))
right now all the dots are blue but I would like them to be colored according to the color column inthe data table
If you are still interested in a mosaic/lattice solution rather than a ggplot2 solution, here you go.
dotPlot( ~ x, data = d, width = 0.1, groups = color,
par.settings=list(superpose.symbol = list(pch = 16, col=c("green", "red"))))
resulting plot
Notice also
as with ggplot2, the colors are not determined by the values in your color variable but by the theme. You can use par.settings to modify this on the level of a plot or trellis.par.set() to change the defaults.
it is preferable to use a formula and data = and to avoid the $ operator.
you can use the width argument rather than breaks if you want to set the bin width. (You can use the center argument to control the centers of the bins if that matters to you. By default, 0 will be the center of a bin.)
You need to add stackgroups=TRUE so that the two different colors aren't plotted on top of each other.
n=20
set.seed(15)
d = data.frame(x = sample(seq(1,10,1), n, replace = TRUE),
color = c(rep("red",n/2), rep("green",n/2)))
table(d$x[order(d$x)])
length(d$x[order(d$x)])
binwidth= 1
ggplot(d, aes(x = x)) +
geom_dotplot(breaks = seq(0.5,10.5,1), binwidth = binwidth,
method="histodot", aes(fill = color),
stackgroups=TRUE) +
scale_x_continuous(breaks=1:10)
Also, ggplot uses its internal color palette for the fill aesthetic. You'd get the same colors regardless of what you called the values of the "color" column in your data. Add scale_fill_manual(values=c("green","red")) if you want to set the colors manually.
I've found many examples describing the assignment of alpha when in a ggplot2 line like so:
scale_alpha( variable, trans = reverse)
ref
However, is there a method to simply invert the scale in aes() inside the geom_*()?
Something like:
geom_point(aes(colour=variableA, alpha=REVERSE(variableB))
(This is a very old question, but I had the same issue and couldn't find an answer. The previous solution by hugh-allan is, as indicated in the Edit note, producing an incorrect legend.)
The settings of the scale should really be in the scale_alpha* parameter. That's where you manage this. The geoms are used for adding the data or setting a style for all points, not tuning a specific scale (otherwise, it would need to be inside the aes() mapping).
To be clear, there are two options in current versions of ggplot2 (using version 3.3.5):
tibble(x = 1:10, y = 1) %>%
ggplot(aes(x, y, alpha = x) +
geom_point(size = 5) +
scale_alpha(trans = reverse_trans())
or, probably more in line with current ggplot documentation:
scale_alpha(range = c(1, 0.1))
i.e., reversing the range of the alpha scale (the default is range = c(1, 0.1)).
If I understand the question correctly, you want to reverse the scale by which alpha is assigned inside a geom...?
For example, by default lower values of x will have lower values of alpha, and appear lighter:
# sample data
tibble(
x = 1:10,
y = 1,
) %>%
ggplot(aes(x, y, alpha = x))+
geom_point(size = 5)
You can reverse it so lower values of x are darker, by using sort() inside aes():
tibble(
x = 1:10,
y = 1,
) %>%
ggplot(aes(x, y, alpha = sort(x, decreasing = TRUE)))+
geom_point(size = 5)
Edit: just realised the legend is incorrect. I guess it's ok if you don't include the legend.
I'm looking for a way to duplicate the kind of Heat Table shown below with R (and possibly ggplot2). Specific time axis are irrelevant; any rectangular table should do.
I've tried to search for Heat map and Heat table in Google, but couldn't find any R package that did the trick.
Thoughts?
require(ggplot2)
df <- data.frame(vaxis = rep(c(letters[1:5], "top"), each = 4),
haxis = rep(c(letters[6:8], "right"), times = 6),
value = rpois(24, lambda = 10))
df$color <- factor(ifelse(df$vaxis == "top" | df$haxis == "right", 1, 0))
ggplot(df, aes(x = haxis, y = vaxis, size = value, color = color)) + geom_point()
Just get your data in a similar format. You could write a function to make the "top" and "right" values normalized marginal sums. Of course lots of tweaks are possible in naming, legends, theme, etc.