Colors

632 views
Skip to first unread message

Francisco

unread,
Nov 18, 2013, 5:58:41 PM11/18/13
to bioge...@googlegroups.com
Dear All

I have been trying to change the colors to the areas defined in my dataset in the piechart, I tried to modify the plot function and played with the "colors_matrix"  to change the default colors but it did not work, andy ideas about how to define a new set of colors for your areas and maybe also for your states?

Best!

Rebecca Harris

unread,
Nov 18, 2013, 6:44:23 PM11/18/13
to bioge...@googlegroups.com
Hey -
Here's what I did. I used the plot function to plot my tree and then used the nodelabels() function to plot the appropriate results_object output as pies. To control the colors, you just use the piecol command and you can play around with the colors in that. 

plot.phylo(my_phylo)

nodelabels(pie=results_object$ML_marginal_prob_each_state_at_branch_top_AT_node[c(29:55),],piecol=my_colors)


R



--
You received this message because you are subscribed to the Google Groups "BioGeoBEARS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to biogeobears...@googlegroups.com.
To post to this group, send email to bioge...@googlegroups.com.
Visit this group at http://groups.google.com/group/biogeobears.
To view this discussion on the web visit https://groups.google.com/d/msgid/biogeobears/fec7eb2c-b8a5-43d8-9d3e-6893868b593f%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Nick Matzke

unread,
Nov 19, 2013, 2:12:19 PM11/19/13
to bioge...@googlegroups.com
Yay people helping each other!

I will just add that display of ancestral geographies is a
difficult problem in big analyses, because of the large
number of possible different ranges, each of which is a
different discrete trait. E.g., for 9 areas you have
(2^9)-1=512 possible ranges. The human eye can really only
meaningfully interpret a small number of discrete colors in
a chart, especially when they are tiny little pie slices or
something.

My "solution", which was just a rough first try, was to make
the default to assign primary colors to the single-area
ranges (A, B, C, D, etc.), and then for combinations, to mix
the colors. This gets you a little bit more out of the
colors but still breaks down with lots of states.

I definitely haven't found the perfect solution! At some
level of complexity, it might be more useful to just sum
over all of the states, and then for each node display a dot
for each area, and shade them by the total probability of
that area being occupied, and not worrying about the exact
state. It's on my wishlist, but lower down than other
features/fixes I need to do (real soon now hopefully, I know
I've been stalling for a bit, I'm finally back in town for 6
weeks though).

Cheers!
Nick
> <mailto:biogeobears%2Bunsu...@googlegroups.com>.
> To post to this group, send email to
> bioge...@googlegroups.com
> <mailto:bioge...@googlegroups.com>.
> Visit this group at
> http://groups.google.com/group/biogeobears.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/biogeobears/fec7eb2c-b8a5-43d8-9d3e-6893868b593f%40googlegroups.com.
> For more options, visit
> https://groups.google.com/groups/opt_out.
>
>
> --
> You received this message because you are subscribed to the
> Google Groups "BioGeoBEARS" group.
> To unsubscribe from this group and stop receiving emails
> from it, send an email to
> biogeobears...@googlegroups.com.
> To post to this group, send email to
> bioge...@googlegroups.com.
> Visit this group at http://groups.google.com/group/biogeobears.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/biogeobears/CAESS275Ndb7_2_Ts9en6ucqNbggfE9WufZm6uY_ZiCgtQUZ6pQ%40mail.gmail.com.
> For more options, visit
> https://groups.google.com/groups/opt_out.

--
====================================================
Nicholas J. Matzke, Ph.D.
NIMBioS Postdoctoral Fellow in Mathematical Biology
National Institute for Mathematical and Biological Synthesis
(NIMBioS, www.nimbios.org)
Cell: 510-301-0179
Email: mat...@nimbios.org
Links to CV, R packages, etc.:
http://phylo.wikidot.com/nicholas-j-matzke

Also: Brian O'Meara Lab
Postdoc office: 425a Hesler
Department of Ecology and Evolutionary Biology
University of Tennessee, Knoxville
http://www.brianomeara.info/

NIMBioS Office:
Claxton Bldg. #110B
Office phone: 865-974-4873

NIMBioS:
1122 Volunteer Blvd., Suite 106
University of Tennessee
Knoxville, TN 37996-3410
Phone: (865) 974-9334
Fax: (865) 974-9300

-----------------------------------------------------
"[W]hen people thought the earth was flat, they were wrong.
When people thought the earth was spherical, they were
wrong. But if you think that thinking the earth is spherical
is just as wrong as thinking the earth is flat, then your
view is wronger than both of them put together."

Isaac Asimov (1989). "The Relativity of Wrong." The
Skeptical Inquirer, 14(1), 35-44. Fall 1989.
http://chem.tufts.edu/AnswersInScience/RelativityofWrong.htm
====================================================

Francisco

unread,
Nov 25, 2013, 10:33:11 AM11/25/13
to bioge...@googlegroups.com
Hi all

Thanks to both of you for the reply! yes with lots of areas it can be quite hard to the eye to interpret the colors, but it is nice to now how to change them ;).

Many thanks!

philli...@noaa.gov

unread,
Jul 19, 2016, 10:23:18 AM7/19/16
to BioGeoBEARS
Hi,
The question and answers below were posted back in 2013, and I haven't seen any update on how to change color schemes (and didn't understand what R. Harris suggested). Has there been any change in the way colors are assigned, or can anyone suggest a way to replace the default color scheme with a specified set of colors? I have a data set with only 4 geographic strata, and the defaults for 2 of them are dark blue and green, with mixed strata being a dark blue-green that is difficult to distinguish (especially printed). 

Phil

Nick Matzke

unread,
Jul 29, 2016, 12:59:02 AM7/29/16
to BioGeoBEARS


On Wednesday, July 20, 2016 at 12:23:18 AM UTC+10, philli...@noaa.gov wrote:
Hi,
The question and answers below were posted back in 2013, and I haven't seen any update on how to change color schemes (and didn't understand what R. Harris suggested). Has there been any change in the way colors are assigned, or can anyone suggest a way to replace the default color scheme with a specified set of colors? I have a data set with only 4 geographic strata, and the defaults for 2 of them are dark blue and green, with mixed strata being a dark blue-green that is difficult to distinguish (especially printed). 

Phil


Hi -- I'm not sure what you mean by "geographic strata". Do you mean areas?  Time stratification is a different thing.  Anyway, assuming areas:

...the function plot_BioGeoBEARS_results(), found e.g. in the example script, has an option, "colors_list_for_states", where you can put in whatever colors you like.

To do this, though, you will have to have clear on your head the difference between areas and states/ranges, and understand how many states you have, and in what order. See:

Get your list of ranges/states, from your list of areas


If you want to access the BioGeoBEARS way of doing colors, see this bit of code here:

====================
areanames = names(tipranges@df)
areanames

include_null_range = TRUE

states_list_0based_index = rcpp_areas_list_to_states_list(areas=areanames, maxareas=max_range_size, include_null_range=include_null_range)

statenames = areas_list_to_states_list_new(areas=areanames, maxareas=max_range_size, include_null_range=include_null_range, split_ABC=FALSE)
statenames

colors_matrix = get_colors_for_numareas(length(areanames))
colors_list_for_states = mix_colors_for_states(colors_matrix, states_list_0based_index, plot_null_range=include_null_range)
colors_list_for_states
====================

The function "mix_colors_for_states" takes whatever colors you have for single areas, and mixes them for the multi-area ranges/states.  If you don't like the base area colors provided by get_colors_for_numareas(length(areanames)), you can always specify your own manually.


The function plot_BioGeoBEARS_results() just wraps the standard APE functions for plotting phylogenies, node labels, and tip labels, so yet another option is to just use those directly.  Type the name of the function: "plot_BioGeoBEARS_results" and hit return to see the internal code.

Cheers,
Nick

Phillip Morin (NOAA Federal)

unread,
Aug 8, 2016, 8:52:14 PM8/8/16
to bioge...@googlegroups.com
Thanks Nick,

That pushed the limits of my R skills, but with a little help I was able to substitute the color matrix for my own.

Thanks for your help.

Phil

--
You received this message because you are subscribed to a topic in the Google Groups "BioGeoBEARS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/biogeobears/-RLk7A-ozZE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to biogeobears...@googlegroups.com.

To post to this group, send email to bioge...@googlegroups.com.

jamessh...@gmail.com

unread,
Mar 31, 2019, 11:07:27 PM3/31/19
to BioGeoBEARS
Hi,

I would also like to create my own color scheme so that I can make the presentation suitable for re/green color blind readers. I have run the script below, but I am struggling to work out how to specify the colors in my 'colors_maxtrix'. I have 9 areas(states) and would like to make them something like ("white", "blue", "orange", "purple", "pink", "cyan", "brown", "gold", "dark red"). I've tried creating the colors matrix using colors_matrix = get_colors_for_numareas(length(areanames)) and then changing the colors in the first column of the matrix, but it didn't work. I've also tried colors_matrix = c("white", "blue", "orange", "purple", "pink", "cyan", "brown", "gold", "dark red") without luck. I'm sure there is a simple solution, but I'm struggling to find it. Can you please help? Thanks for your time and for this great program. 

Regards,
James

Nick Matzke

unread,
Apr 1, 2019, 12:12:22 AM4/1/19
to bioge...@googlegroups.com
Hi! As a red-green colorblind person myself I support this work!

On my iPhone, but probably the key is to run that code on defaults and then look at the structure of colors_matrix — I think it is more than just a list of colors... cheers! Nick
--
You received this message because you are subscribed to the Google Groups "BioGeoBEARS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to biogeobears+unsubscribe@googlegroups.com.

To post to this group, send email to bioge...@googlegroups.com.
Visit this group at https://groups.google.com/group/biogeobears.

James Shelley

unread,
Apr 1, 2019, 1:05:58 AM4/1/19
to bioge...@googlegroups.com
Apparently 4.5% of the population are! Thanks for the quick response. The colors_matrix run on my data with the default code looks like this (below).  I’m unsure what it means though. Why are there only 3 colors and how are they allocated to each of the 9 areas (ranges)? There are 256 possible states for my dataset. Once I work that out, I imagine I just manually create a similar table with the colors that I want and then use that?

James


colors_matrix = get_colors_for_numareas(length(areanames))

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
red    255  255  170    0    0    0    0  170  255
green    0  170  255  255  255  170    0    0    0
blue     0    0    0    0  170  255  255  255  170

To unsubscribe from this group and stop receiving emails from it, send an email to biogeobears...@googlegroups.com.

To post to this group, send email to bioge...@googlegroups.com.
Visit this group at https://groups.google.com/group/biogeobears.

Nick Matzke

unread,
Apr 2, 2019, 6:10:13 PM4/2/19
to bioge...@googlegroups.com
Hi,

Sorry for the slow reply.  The color stuff is coming back to me now....

BACKGROUND

Here's the basic problem I was confronted with in designing the BioGeoBEARS defaults colors: the human eye can only comfortably read a few colors in a plot (10 or so).  You can distinguish many more colors of course, but it becomes quite challenging to tell which shade of light reddish-orange in the legend corresponds to which shade of light reddish-orange in the plot. (This is often a problem in geological maps, especially if you are colorblind like me.)

In biogeographical problems, we often have dozens or hundreds of possible states in the state space, ie dozens or hundreds of possible ranges that a particular species might live in. This is because:

number of possible ranges = 2^(number of areas)

i.e., 10 areas means there are 2^10=1024 possible combinations of presence/absence in the 10 areas = 1024 possible ranges

Obviously, a legend with 1024 (or even 100 or 50) color boxes in it is pretty impractical.  But, if we are going to color things in at all (not required, but useful for quick viewing of the major patterns, we have to have some way of assigning colors to all those ranges.

My solution was:
1. Pick default highly distinct / primary colors for the single-area ranges (e.g. red for A, yellow for B)
2. For multi-area ranges, mix the colors (so, AB would mix red and yellow and produce orange for AB)
3. A range of "all areas occupied" gets white

This gets to what the colors matrix is for:


On Mon, Apr 1, 2019 at 6:05 PM James Shelley <jamessh...@gmail.com> wrote:
Apparently 4.5% of the population are! Thanks for the quick response. The colors_matrix run on my data with the default code looks like this (below).  I’m unsure what it means though. Why are there only 3 colors and how are they allocated to each of the 9 areas (ranges)? There are 256 possible states for my dataset. Once I work that out, I imagine I just manually create a similar table with the colors that I want and then use that?

James


colors_matrix = get_colors_for_numareas(length(areanames))

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
red    255  255  170    0    0    0    0  170  255
green    0  170  255  255  255  170    0    0    0
blue     0    0    0    0  170  255  255  255  170

OK, looking at the colors matrix, 

...these are the single-area colors for the 9 areas you have in your analysis.  In R and many computer systems, one of the ways of specifying colors is with the RGB (red green blue) system. Because we have 3 color pigments in our eyes (red green blue, although for red-green colorblind people like me the red and green pigments overlap in their color absorption more than usual), all colors can be made by combining the 3 primary colors.  Computers like to code things in bytes, a byte=8 bits, and numbers from 1-256 (or 0-255) can be encoded in a byte. So RGB colors can be specified with 3 numbers.  This is done for the 9 areas above.  Translating it:

area 1 is pure red
area 2 is orange
area 3 is yellow I think
area 8 is pure blue
etc.

With fewer areas this matrix will be smaller with different defaults (although red is usually first).



SOLUTION 1

Anyway, so one way to change the colors is change this colors_matrix to give the individual areas different colors by putting different numbers into that matrix



SOLUTION 2

You can also get the full list of colors for the full list of ranges, the code for this is:

============
areanames = names(tipranges@df)
areanames

include_null_range = TRUE

states_list_0based_index = rcpp_areas_list_to_states_list(areas=areanames, maxareas=max_range_size, include_null_range=include_null_range)

statenames = areas_list_to_states_list_new(areas=areanames, maxareas=max_range_size, include_null_range=include_null_range, split_ABC=FALSE)
statenames

relprobs_matrix = resDEC$ML_marginal_prob_each_state_at_branch_top_AT_node
MLprobs = get_ML_probs(relprobs_matrix)
MLstates = get_ML_states_from_relprobs(relprobs_matrix, statenames, returnwhat="states", if_ties="takefirst")

colors_matrix = get_colors_for_numareas(length(areanames))
colors_list_for_states = mix_colors_for_states(colors_matrix, states_list_0based_index, plot_null_range=include_null_range)
colors_list_for_states
============

Instead of using mix_colors_for_states() to mix the single-area colors in "colors_matrix", you could just type out a list of colors and put it into "colors_list_for_states" directly.  This might be a long list though, if you have a lot of states (9 areas is 2^9=512 states, unless you set max_num_areas below 9).


SOLUTION 3

It would be simpler to use the default colors_list_for_states, but then change individual colors as desired, this requires you to get the list of ranges/states, compare to the list of colors, and change the colors_list_for_states manually. The 4th state/range will be the 4th color, etc.

Get your list of ranges/states, from your list of areas



SOLUTION 4

Whatever you do, there is no requirement to have a legend listing every last color for every last state. You could just have a small legend with the single-area colors, and then explain that multi-area ranges have mixed colors. Or, you could just add a few legend entries for the multi-range states that are actually observed/inferred (often there are only a few).

Often, legends aren't needed at all, as by default the plots have the actual range abbreviations in them (looks best with single-letter abbreviations), so all you really need is the caption to explain A=Africa, B=Europe, etc.  Often people like to have a map with the single areas with corresponding colors, this has to be done by hand in Adobe Illustrator or Inkscape (free) or whatever.  (Or with some rather advanced R GIS skills, I can do it but it is hard to type up general instructions and you need a GIS shapefile with all the areas etc.)

I hope that helps, cheers!
Nick

 

To unsubscribe from this group and stop receiving emails from it, send an email to biogeobears...@googlegroups.com.
To post to this group, send email to bioge...@googlegroups.com.
Visit this group at https://groups.google.com/group/biogeobears.
To view this discussion on the web visit https://groups.google.com/d/msgid/biogeobears/0e9d3105-f25c-4c5b-8aeb-6198fde3a208%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "BioGeoBEARS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to biogeobears...@googlegroups.com.
To post to this group, send email to bioge...@googlegroups.com.
Visit this group at https://groups.google.com/group/biogeobears.
To view this discussion on the web visit https://groups.google.com/d/msgid/biogeobears/CAJdu7BC1RshxsHi0W0VN9cfEUi7myoUqKCbqaDUkBKPJvnizfg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "BioGeoBEARS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to biogeobears...@googlegroups.com.
To post to this group, send email to bioge...@googlegroups.com.
Visit this group at https://groups.google.com/group/biogeobears.

James Shelley

unread,
Apr 3, 2019, 10:14:47 PM4/3/19
to bioge...@googlegroups.com
Hi Nick,

Thanks again for your detailed reply. I went with option 3 in the end. Although I have 256 possible states (I've restricted the max areas to 4) only about 12 are visible on the pie charts; that is they have substantial ancestral range probabilities. I've been able to work out my own colour scheme based on those, although even that is a pain! I used this RGB color codes chart to work out the best colors for the job and what to code them as (https://www.rapidtables.com/web/color/RGB_Color.html).

Regards,
James

nepenthesbaphomet

unread,
Dec 10, 2025, 8:28:03 AM12/10/25
to BioGeoBEARS
This is a little late for the OP but I thought this script I came up with to plot custom colors would be helpful for others since its something I wanted. I mainly want the colors to be consistent with my visualized models and other plots. This script performs a similar color blending logic like whats already implemented in biogeobears but with your own defined color palette. This pallet is defined using hex codes and seems to work OK. I cant guarantee your color pallet will look OK once blended, this might take trial and error!

```
# get ranges based on biogeobears scripts
areas = getareas_from_tipranges_object(tipranges)
states_list_0based = rcpp_areas_list_to_states_list(areas=areas, maxareas=max_range_size, include_null_range=TRUE)
ranges_list = NULL
for (i in 1:length(states_list_0based))
{    
  if ( (length(states_list_0based[[i]]) == 1) && (is.na(states_list_0based[[i]])) )
  {
    tmprange = "_"
  } else {
    tmprange = paste(areas[states_list_0based[[i]]+1], collapse="")
  }
  ranges_list = c(ranges_list, tmprange)
}
# Look at the ranges list
ranges_list

# define your custom color palette 
base_colors = c("N" = "#6a7c8aff", "C" = "#228cd3ff", "S" = "#00c66aff",
                "W" = "#f1be2cff", "E" = "#e94439ff", "F" = "#934daaff",
                "I" = "#00b492ff", "A" = "#f59327ff", "M" = "#d24b17ff")
transparent=("#00000000")
# if you dont intend on showing the pie chart, use something like "needed_codes"
# and descrie the nodes you know will need to be colored.
#needed_codes <- c(c(names(base_colors)),
#                  "NE","WE","NW","NWE",
#                  "CS","WEF","NC",
#                  "CS","EI","FM",
#                  "WEI","NCS")
# But the pie chart will end up with many transparent nodes
# To get a blend of all possible colors, even though most of them
# wont actually show up just use the range_list
needed_codes <- ranges_list


# blend code combinations function
blend_hex <- function(hex_vec) {
  rgb_vals <- t(col2rgb(hex_vec, alpha = TRUE))
  avg <- colMeans(rgb_vals)
  rgb(avg["red"], avg["green"], avg["blue"], avg["alpha"], maxColorValue = 255)
}

# create color for each needed code function
get_color <- function(code) {
  letters <- strsplit(code, "")[[1]]
  blend_hex(base_colors[letters])
}

# use sapply to create the new colors
color_map <- setNames(sapply(needed_codes, get_color), needed_codes)

# now build vector, it should match to the ranges_list
my_colors <- sapply(ranges_list, function(code) {
  if (code %in% names(color_map) || code %in% names(base_colors)) color_map[[code]] else transparent
})
my_colors
```

You can then just use this in the biogeobears plotting function:
"colors_list_for_states = my_colors"

I think the main thing to note, is that for my tree of ca. 140 taxa the biogeography didn't result in a huge number of combinations. But if you end up with a lot of combinations this script doesn't solve the overall issue of custom colors being distinguishable with many combinations.

Nick Matzke

unread,
Dec 10, 2025, 3:47:53 PM12/10/25
to bioge...@googlegroups.com
Thanks for sharing!

Yes, once you have many states, life gets complex, humans can notice tiny color differences, but seeing a color on a legend etc. & matching to somewhere in a figure can be nontrivial once there are many colors -- probably worse for me as I am anomalous trichromatic (ie red-green colorblind, although this just means less sensitive to the red/green difference).  But usually people mostly also write the most-probable ranges on the nodes etc. 

Cheers,
Nick


Reply all
Reply to author
Forward
0 new messages