idiogramFISH: Shiny App. Idiograms with Marks and Karyotype Indices

Documentation: idiogramFISH 2.0.13.9000DocumentationidiogramFISH 2.0.13.9000

Introduction

The goal of idiogramFISH functions or the shiny-app is to plot karyotypes, plasmids and circular chr. having a set of data.frames for chromosome data and optionally marks’ data (Roa and PC Telles, 2021). Karyotypes can also be plotted in concentric circles.

It is possible to calculate also chromosome and karyotype indexes (Romero-Zarco, 1986; Watanabe et al., 1999) and classify chromosome morphology in the categories of Levan (1964), and Guerra (1986).

Six styles of marks are available: square (and squareLeft), dots, cM (cMLeft), cenStyle, upArrow (downArrow), exProtein (inProtein) (in column style in dfMarkColor data.frame); its legend (label) (parameter legend) can be drawn inline or to the right (aside) of karyotypes. Three styles of centromere are available: rounded, triangle and inProtein (cenFormat parameter). Chromosome regions (column chrRegion in dfMarkPos data.frame) for monocentrics are p (short), q (long), cen, pcen, qcen. The last three cannot accommodate most mark styles, but can be colored. The region w (whole) can be used both in monocentrics and holocentrics.

IdiogramFISH was written in R (R Core Team, 2019) and also uses crayon (Csárdi, 2017), tidyr (Wickham and Henry, 2020), plyr (Wickham, 2011) and dplyr packages (Wickham et al., 2019). Documentation was written with R-packages roxygen2 (Wickham et al., 2018), usethis (Wickham and Bryan, 2019), bookdown (Xie, 2016), knitr (Xie, 2015), pkgdown (Wickham and Hesselberth, 2019), Rmarkdown (Xie et al., 2018), rvcheck (Yu, 2019a), badger (Yu, 2019b), kableExtra (Zhu, 2019), rmdformats (Barnier, 2020) and RCurl (Temple Lang and CRAN team, 2019). For some vignette figures, packages rentrez (Winter, 2017), phytools (Revell, 2012), ggtree (Yu et al., 2018), ggplot2 (Wickham, 2016) and ggpubr (Kassambara, 2019) were used.

In addition, the shiny app runBoard() uses shiny (Chang et al., 2021), shinydashboard (Chang and Borges Ribeiro, 2018), rhandsontable (Owen, 2018), gtools (Warnes et al., 2020) and rclipboard (Bihorel, 2021).

Run the Shiny app with docker

  • No need to install R
  • Install docker on your system
  • Make sure you can run a docker example image, i.e. ubuntu, in the console (system terminal)
docker pull fercyto/idiogramfish

# Run the image
docker run -d -p 8080:8080 fercyto/idiogramfish

In your internet browser go to http://localhost:8080

# Stop the container
docker ps
docker stop {container id}

Installation instructions

CRAN CRAN 2.0.13 2.0.13  DOI: 10.5281/zenodo.3579417DOI10.5281/zenodo.3579417

You can install idiogramFISH from CRAN with:

install.packages("idiogramFISH")

Windows users: To avoid installation of R-packages in OneDrive

.libPaths()          # read library location
.libPaths("D:R/lib") # set

To do that permanently: Search (magnifier) “environment variables” and set R_LIBS_USER to D:\R\lib (example)

Other option: something in the line of this link

Need help?

Vignettes

Online:

vignettes: idiogramFISH 2.0.13vignettesidiogramFISH 2.0.13

Launch vignettes from R for the installed version:

library(idiogramFISH)
packageVersion("idiogramFISH")
browseVignettes("idiogramFISH")

Citation

To cite idiogramFISH in publications, please use:

Roa F, Telles M. idiogramFISH: Shiny app. Idiograms with Marks and Karyotype Indices. doi: 10.5281/zenodo.3579417

To write citation to file:

sink("idiogramFISH.bib")
toBibtex(citation("idiogramFISH"))
sink()

1 Working online

Shiny App in the cloud availability:
shinyapps.io

Each chapter has a jupyter version. A jupyter notebook seems an interactive vignette.

They are hosted in github

They can be accessed with google colab to work online.

Open in ColabOpen in Colab  Github  
3 Minimal examples link Raw
4 Plotting chromosomes link Raw
5 Multiple OTUs link Raw
6 Changing units link Raw
7 GISH link Raw
8 Groups link Raw
9 Circular Plots link Raw
10 Plotting alongside phylogeny link Raw
11 Citrus link Raw
12 Human Karyotype link Raw


Chapters can be accessed locally in your jupyter-lab or jupyter notebook

After installing jupyter, you can install the R kernel with:

install.packages("IRkernel")
IRkernel::installspec()

2 Shiny App

Attention Windows users, might require the last R version to plot correctly.

library(idiogramFISH)
runBoard()

Shiny App in the cloud availability:
shinyapps.io

3 Minimal examples


Jupyter interactive version:

Open in ColabOpen in Colab   Github   Raw


3.1 Monocentrics

Define your plotting window size with something like par(pin = c(10, 6)), or with svg(), png(), etc. Add chromosome morphology according to Guerra (1986) or (Levan et al., 1964)

library(idiogramFISH)

data(dfOfChrSize) # chromosome data
data(dfMarkColor) # mark general data
data(dfOfMarks2)  # mark position data (inc. cen.)

# column Mbp not for plotting purposes
dfOfChrSize$Mbp <- (dfOfChrSize$shortArmSize + dfOfChrSize$longArmSize) * 100

svg("dfOfChrSize.svg", width = 10, height = 6)
# png("dfOfChrSize.png", width = 500, height = 400)
plotIdiograms(dfChrSize  = dfOfChrSize,  # data.frame of chr. size
  dfMarkColor = dfMarkColor,  # d.f of mark style <- Optional
  dfMarkPos = dfOfMarks2,     # d.f of mark positions (includes cen. marks)

  karHeight = 5,              # kar. height
  chrWidth = 1.2,             # chr. width
  chrSpacing = 1,             # space among chr.

  morpho = "Guerra",          # chr. morpho. classif. (Guerra, Levan, both, "" ) ver. >= 1.12 only
  chrIndex = "CI",            # cen. pos. (CI, AR, both, "" ) ver. >= 1.12 only
  chrSize = TRUE,             # add chr. sizes under chr.
  chrSizeMbp = TRUE,          # add Mbp sizes under chr. (see above)

  rulerPos = 0,               # position of ruler
  ruler.tck = -0.01,          # size and orientation of ruler ticks
  rulerNumberSize = .8        # font size of rulers
  , xPosRulerTitle = 3        # pos of ruler title

  , legendWidth = 1          # width of legend items
  , fixCenBorder = TRUE      # use chrColor as border color of cen. or cen. marks
  , distTextChr = 1.2        # chr. text separation

  , xlimLeftMod = 0          # xlim left param.
  , xlimRightMod = 3         # xlim right param.
  , ylimBotMod = 0           # modify ylim bottom argument
  , ylimTopMod = 0           # modify ylim top argument
)
dev.off() # close svg()

Let’s explore the data.frames for monocentrics:

If only one species, column OTU is optional

dfOfChrSize
chrName shortArmSize longArmSize Mbp
1 3 4 700
2 4 5 900
3 2 3 500
X 1 2 300
dfMarkColor
markName markColor style
5S red dots
45S chartreuse3 square
DAPI blue square
CMA darkgoldenrod1 square

p, q and w marks can have empty columns markDistCen and markSize since v. 1.9.1 to plot whole arms (p, q) and whole chr. w.

# mark position data (inc. cen.) 
dfOfMarks2
chrName markName chrRegion markSize markDistCen
1 5S p 1 0.5
1 45S q 1 0.5
X 45S p NA NA
3 DAPI q 1 1.0
1 DAPI cen NA NA
X CMA cen NA NA

3.2 Holocentrics

library(idiogramFISH)

# load some package data.frames - optional
data(dfChrSizeHolo, dfMarkColor, dfMarkPosHolo)

# column Mbp not for plotting purposes
dfChrSizeHolo$Mbp <- dfChrSizeHolo$chrSize * 100

# svg("testing.svg",width = 14, height = 8 )
par(mar = c(0, 0, 0, 0), omi = rep(0, 4))

plotIdiograms(dfChrSize  = dfChrSizeHolo, # data.frame of chr. size
  dfMarkColor = dfMarkColor,   # df of mark style
  dfMarkPos  = dfMarkPosHolo,  # df of mark positions

  addOTUName = FALSE,        # do not add OTU names
  distTextChr = 1,           # chr. name distance to chr.
  chrSize = TRUE,            # show chr. size under chr.
  chrSizeMbp = TRUE,         # show chr. size in Mbp under chr. requires Mbp column

  rulerPos = -0.1,           # position of ruler
  rulerNumberPos = .9        # position of numbers of rulers
  , xPosRulerTitle = 3       # pos. of ruler title (units)

  , xlimLeftMod = 2           # modify xlim left argument of plot
  , ylimBotMod = .2           # modify ylim bottom argument of plot
  , legendHeight = .5         # height of legend labels
  , legendWidth = 1.2         # width of legend labels
  , xModifier = 20            # separ. among chromatids
)

# dev.off() # close svg()

Let’s explore the data.frames for holocentrics:

  • chromosome data, if only 1 species, column OTU is optional
dfChrSizeHolo
chrName chrSize Mbp
1 3 300
2 4 400
3 2 200
4 5 500
  • mark general data
dfMarkColor
markName markColor style
5S red dots
45S chartreuse3 square
DAPI blue square
CMA darkgoldenrod1 square
  • mark position data, if only 1 species, column OTU is optional (mandatory if in d.f of Chr. Size)
dfMarkPosHolo
chrName markName markPos markSize
3 5S 1.0 0.5
3 DAPI 1.5 0.5
1 45S 2.0 0.5
2 DAPI 2.0 0.5
4 CMA 2.0 0.5
4 5S 0.5 0.5

3.3 Plotting both mono. and holo.

Merge data.frames with plyr (Wickham, 2011)

# chromosome data, if only 1 species, column OTU is optional
require(plyr)
dfOfChrSize$OTU   <- "Species mono"
dfChrSizeHolo$OTU <- "Species holo"

monoholoCS <- plyr::rbind.fill(dfOfChrSize, dfChrSizeHolo)

dfOfMarks2$OTU     <- "Species mono"
dfOfMarks2[which(dfOfMarks2$markName == "5S"), ]$markSize <- .7
dfMarkPosHolo$OTU <- "Species holo"

monoholoMarks <- plyr::rbind.fill(dfOfMarks2, dfMarkPosHolo)

Plot

library(idiogramFISH)

# svg("testing.svg",width = 14, height = 10 )
png("monoholoCS.png", width = 700, height = 600)
par(mar = rep(0, 4))
plotIdiograms(dfChrSize   = monoholoCS,   # data.frame of chr. size
  dfMarkColor = dfMarkColor,   # df of mark style
  dfMarkPos   = monoholoMarks, # df of mark positions, includes cen. marks

  chrSize     = TRUE,         # show chr. size under chr.

  squareness  = 4,            # vertices squareness
  addOTUName  = TRUE,         # add OTU names
  OTUTextSize = .7,           # font size of OTU
  distTextChr = .5,           # separ. among chr. and text and among chr. name and indices

  karHeiSpace = 4,            # karyotype height inc. spacing
  karIndexPos = .2,           # move karyotype index

  legendHeight = 1,            # height of legend labels
  legendWidth = 1,             # width of legend labels
  fixCenBorder = TRUE,         # use chrColor as border color of cen. or cen. marks

  rulerPos    = 0,             # position of ruler
  ruler.tck   = -0.02,         # size and orientation of ruler ticks
  rulerNumberPos = .9,         # position of numbers of rulers
  xPosRulerTitle = 3.5,        # ruler title (units) position

  xlimLeftMod = 1,             # modify xlim left argument of plot
  xlimRightMod = 3,            # modify xlim right argument of plot
  ylimBotMod = 0.2             # modify ylim bottom argument of plot

  , chromatids = FALSE         # do not show separ. chromatids

  # ,useOneDot = TRUE

  # ,circularPlot = TRUE       # circularPlot
  # ,shrinkFactor = .9         # percentage 1 = 100% of circle with chr.
  # ,circleCenter = 3          # X coordinate of circleCenter (affects legend pos.)
  # ,chrLabelSpacing = .9      # chr. names spacing

  # ,OTUsrt = 0                # angle for OTU name (or number)
  # ,OTUplacing = "number"     # Use number and legend instead of name
  # ,OTULabelSpacerx = -0.6    # modify position of OTU label, when OTUplacing = "number" or "simple"
  # ,OTUlegendHeight = 1.5     # space among OTU names when in legend - OTUplacing
  # ,separFactor = 0.75        # alter separ. of kar.
)
dev.off() # close png

4 Plotting chromosomes


Jupyter interactive version:

Open in ColabOpen in Colab   Github   Raw


This guide shows how to plot idiograms of measured karyotypes and optionally marks.

4.1 Load package

Visit the Introduction for installation instructions

library(idiogramFISH) 

4.2 Plot monocentrics

Initially you have to put chromosome data in data.frames.

Main three data.frames:

  • One for chr. sizes (parameter dfChrSize)
  • One for marks’ positions (parameter dfMarkPos)
  • One (optional) for mark style (parameter dfMarkColor)

For a way to start with only one data.frame of chr. size and marks’ pos., see Chapter 8.

data.frame of chr. size

# Example data.frame to write in R, use: (column OTU is optional if only 1 OTU)
mydfChrSize <- read.table(text =
  "            OTU chrName shortArmSize longArmSize
  \"Species one\"   1     1.5         2.0
  \"Species one\"   2     2.0         2.5
  \"Species one\"   3     1.0         1.5
  \"Species one\"   B     2.0         3.5",  header = TRUE, stringsAsFactors = FALSE, fill = TRUE)
OTU chrName shortArmSize longArmSize
Species one 1 1.5 2.0
Species one 2 2.0 2.5
Species one 3 1.0 1.5
Species one B 2.0 3.5

loading saved data:

If you use RStudio, in the menu “Session”, use “Set working directory” for choosing your desired folder or:

setwd("~/folder/subfolder")

Open your chromosome data data.frame importing it from a .csv (read.csv) or .xls file (readxl).

mydfChrSize<-read.csv("somefile.csv")

Editing a data.frame:

bigdfOfChrSize <- edit(bigdfOfChrSize, edit.row.names = FALSE)

For fixing column names use:

colnames(mydfChrSize)<-c("OTU", "chrName","shortArmSize","longArmSize")

Marks’ position data

Open or write your mark positions in a data.frame. This data.frame has the marks present in all karyotypes with position info. This data.frame has also the centromeric marks present in all karyotypes.

Column chrRegion defines the arm or region of occurrence (p, q, w, cen). Distance to centromere is defined in markDistCen.

# We will use column OTU if data.frame because chromosome size df has it
mydfOfMarks <- read.table(text =
  "            OTU chrName markName chrRegion markSize markDistCen
\"Species one\"      1      45S       p       NA         NA     # no measure (NA) means whole arm
\"Species one\"      1       5S       q      0.5         0.5
\"Species one\"      B  \"B mark\"    w       NA         NA     # w for whole chromosome
\"Species one\"      B  \"cB mark\"   q       NA         1.0
\"Species one\"      2    cgene4      p        1         1.0
\"Species one\"      2    cgene1      q        1         1
\"Species one\"      2    cgene2      q      0.5         2.0
\"Species one\"      3     DAPI       q       NA         1
\"Species one\"      3    cgene3      p       NA         0.5
\"Species one\"      1     DAPI       pcen
\"Species one\"      3      CMA       qcen
\"Species one\"      2      CMA       cen", header = TRUE, stringsAsFactors = FALSE, fill = TRUE)
OTU chrName markName chrRegion markSize markDistCen
Species one 1 45S p NA NA
Species one 1 5S q 0.5 0.5
Species one B B mark w NA NA
Species one B cB mark q NA 1.0
Species one 2 cgene4 p 1.0 1.0
Species one 2 cgene1 q 1.0 1.0
Species one 2 cgene2 q 0.5 2.0
Species one 3 DAPI q NA 1.0
Species one 3 cgene3 p NA 0.5
Species one 1 DAPI pcen NA NA
Species one 3 CMA qcen NA NA
Species one 2 CMA cen NA NA

For fixing column names use something like:

colnames(mydfMarkColor)<-c("OTU", "chrName","markName","chrRegion","markSize","markDistCen") 

Marks’ general data

This data.frame is optional. It has the marks present in all karyotypes without position info.

It includes color and style. If the style column is not present, param. defaultStyleMark = "square" will be used during plotting.

Note the cenStyle to make constrictions, mimicking centromeres.

# From scratch:
mydfMarkColor <- read.table(text =
  " markName      markColor      style
        5S      red            dots
       45S      chartreuse3    square
    cgene1      chocolate      upArrow
    cgene2      salmon         downArrow
    cgene3      \"#056522\"    cMLeft
      DAPI      dodgerblue     cM
\"cB mark\"     black          cenStyle
       CMA      darkgoldenrod1 square
\"B mark\"      black          square
    cgene4      cornflowerblue exProtein",  header = TRUE, stringsAsFactors = FALSE, fill = TRUE)
markName markColor style
5S red dots
45S chartreuse3 square
cgene1 chocolate upArrow
cgene2 salmon downArrow
cgene3 #056522 cMLeft
DAPI dodgerblue cM
cB mark black cenStyle
CMA darkgoldenrod1 square
B mark black square
cgene4 cornflowerblue exProtein

For fixing column names use:

colnames(mydfMarkColor)<-c("markName", "markColor","style") 
# if style column is not present it will be filled with "square"

Add some text to the right

We will use column note to add a note to the right of the karyotype of the specified OTU (see column OTU)

notesdf<-read.table(text=
"            OTU    note
\"Species one\"   \"Author notes\"  ", header = TRUE, stringsAsFactors = FALSE, fill = TRUE)

For adding just the OTU name (from column OTU of data.frame of chr. size) to the right, use OTUasNote = TRUE

Plotting

You can plot without marks (use only 1st data.frame), but we will use all 4 data.frames created. By default the function will calculate indices (Romero-Zarco, 1986; Watanabe et al., 1999) and morphological categories of Guerra (1986) and Levan (1964). Use parameters chrIndex and morpho of the function plotIdiograms to modify that. See ?plotIdiograms.

The cM style of mark always adds the name as if legend = "inline", even when legend = "aside" (default).

# svg("mydfChrSize.svg",width = 12, height = 6 )

par(mar = c(0, 0, 0, 0))

plotIdiograms(dfChrSize = mydfChrSize,     # chr. size data.frame
  dfMarkPos = mydfOfMarks,     # mark position data.frame (inc. cen.)
  dfMarkColor = mydfMarkColor, # mark style d.f.

  chrSpacing = .6,              # separ. among chr.
  distTextChr = .7,             # separation among text and chr. names and ind.
  orderChr = "name",            # order chr. by name
  karHeiSpace = 2               # vertical size of karyotype including spacer

  , arrowhead = .5             # proportion of head of arrow

  , fixCenBorder = TRUE        # use chrColor as border color of cen. or cen. marks
  , legendWidth = .8           # legend item width
  , legendHeight = .5          # legend item height
  , markLabelSpacer = 2        # legend spacer
  , lwd.mimicCen = 2.5         # constric. mark line width

  , rulerPos = 0               # ruler position
  , ruler.tck = -0.01          # ticks of ruler size and orientation
  , xPosRulerTitle = 2.5       # ruler units pos.

  , markPer = "45S"            # show mark % of chr.  under kar.
  , showMarkPos = TRUE         # show position of marks under kar. See bToRemove
  , bToRemove = c("B mark", "cB mark") # bands to remove from pos. calc. See showMarkPos

  , notes = notesdf              # data.frame with notes
  , notesTextSize = 1.3        # font size of notes
  , notesPosX = .2             # space from chr. (right) to note

  , ylimBotMod = 2             # modify ylim bottom argument
  , ylimTopMod = 0             # modify ylim top argument
  , xlimLeftMod = 2            # modify left xlim
  , xlimRightMod = 3           # modify right xlim
  , lwd.cM = 2                 # thickness of cM marks
  , pattern = "^c"             # regex pattern to remove from mark names
  , remSimiMarkLeg = TRUE      # remove pseudoduplicated mark names from legend (same after pattern removal)
  , legendYcoord = -1.2
  # ,legend = "inline"          # legend next to chr.
  , bannedMarkName = c("B mark", "cB mark")  # remove from legends
) # ;  dev.off() # close .svg

Vertices when centromereSize = 0 are rounded:

png("mydfChrSize2.png", width = 550, height = 550)
par(mar = c(0, 0, 0, 0))
plotIdiograms(dfChrSize   = bigdfOfChrSize[1:8, ],  # chr. size data.frame
  dfMarkColor = mydfMarkColor, # mark style df
  dfMarkPos   = bigdfOfMarks,  # mark position df

  centromereSize = 0,         # <- HERE

  squareness = 3,             # vertices squareness
  chrSpacing = .7,            # space among chr.
  karHeight = 2,              # karyotype rel. height
  karHeiSpace = 4,            # vertical size of karyotype including spacer
  amoSepar = 2.5,             # separation among karyotype

  indexIdTextSize = .8,       # font size of chr. name and indices
  karIndexPos = .1,           # position of kar. index
  markLabelSize = .7,         # font size of mark legends
  fixCenBorder = FALSE,       # do not use chrColor as border color of cen. or cen. marks
  distTextChr = .8,           # separation among chr. and ind.

  rulerPos = 0,               # ruler position
  ruler.tck = -0.01,          # ticks of ruler size and orientation
  xPosRulerTitle = 2.6,       # ruler units pos.

  xlimLeftMod = 2,            # modify xlim left argument
  ylimBotMod = 0.4,           # modify ylim bottom argument
  ylimTopMod = 0              # modify ylim top argument
  , lwd.cM = 2                # thickness of cM marks
)
dev.off()

There is no need to add dfMarkColor and you can also use the parameter mycolors (optional too), to establish marks’ colors. Colors are assigned depending on the order of marks, i.e.:

unique(mydfOfMarks$markName) 

Let’s use the cM style of marks. A protruding line.

cM style does not apply to centromere marks. To make something similar, use centromereSize = 0, legend = "inline" and fixCenBorder = FALSE.

charVectorCol <- c("tomato3", "darkolivegreen4", "dfsd", "dodgerblue", "chartreuse3")

# Modify size of kar. to use rulerInterval and ceilingFactor (>= 1.13)
quo <- 9
dfOfChrSize2 <- dfOfChrSize
dfOfChrSize2$shortArmSize <- dfOfChrSize$shortArmSize / quo
dfOfChrSize2$longArmSize <- dfOfChrSize$longArmSize / quo
dfOfMarks2b <- dfOfMarks2
dfOfMarks2b$markSize <- dfOfMarks2$markSize / quo
dfOfMarks2b$markDistCen <- dfOfMarks2$markDistCen / quo

png("dfOfChrSizeVector.png", width = 1000, height = 450)
par(mar = rep(0, 4))
plotIdiograms(dfChrSize = dfOfChrSize2,    # d.f. of chr. sizes
  dfMarkPos = dfOfMarks2b,     # d.f. of marks' positions
  defaultStyleMark = "cM",     # forces "cM" style in d.f dfMarkColor (exc. 5S)

  mycolors = charVectorCol,    # colors to use

  distTextChr = 0.5,           # separ. text and chr.

  markLabelSize = .7,            # font size for labels (legend)
  lwd.cM = 2,                    # width of cM marks
  legendWidth = 0.9,             # legend item width
  legendHeight = .5,

  rulerPos = 0,                  # ruler position
  ruler.tck = -0.01,             # ruler tick orientation and length
  rulerNumberSize = .5           # ruler font size
  , xPosRulerTitle = 2.8         # ruler units pos.

  , xlimRightMod = 1             # modify xlim right arg.
)
dev.off() # close png

4.3 Plot holocentrics

Initially you have to put your chromosome data in data.frames.

Main three data.frames:

  • One for chr. sizes (parameter dfChrSize)
  • One for marks’ positions (parameter dfMarkPos)
  • One (optional) for mark style (parameter dfMarkColor)

For simplicity, I call a holocen. any karyotype without centromeres.

Accordingly, they lack the columns: shortArmSize and longArmSize.

From scratch:

# Example data.frame written in R, use: (column OTU is optional if only 1 OTU)
mydfChrSizeHolo <- read.table(text =
  "            OTU chrName chrSize
\"Species one\"   1     6.5
\"Species one\"   2     5.0
\"Species one\"   3     4.0
\"Species one\"   4     4.0
\"Species one\"   X     3.0    ",  header = TRUE, stringsAsFactors = FALSE, fill = TRUE)
OTU chrName chrSize
Species one 1 6.5
Species one 2 5.0
Species one 3 4.0
Species one 4 4.0
Species one X 3.0

or loading saved data:

If you use RStudio, in menu “Session”, open “Set working directory” for choosing your desired folder or:

setwd("~/folder/subfolder")

Open your chromosome data as data.frame importing it from a .csv (read.csv) or .xls file (readxl).

mydfChrSize<-read.csv("somefile.csv")

For fixing column names use:

colnames(mydfChrSize)<-c("OTU", "chrName","chrSize")

Get marks general data

Put your mark data in a data.frame. This data.frame has the marks present in all karyotypes without position info. If the style column is not present, param. defaultStyleMark = "square" will be used during plotting.

# From scratch:
mydfMarkColorHolo <- read.table(text =
  "  markName    markColor      style
     5S        red            dots
     45S       chartreuse3    square
     gene2     salmon         downArrow
     gene3     \"#056522\"    cMLeft
     gene4     darkmagenta    cM
     DAPI      dodgerblue     square
     protein   cornflowerblue exProtein
     B         black          square
     gene1     chocolate      upArrow
     CMA       darkgoldenrod1 square",  header = TRUE, stringsAsFactors = FALSE, fill = TRUE)
markName markColor style
5S red dots
45S chartreuse3 square
gene2 salmon downArrow
gene3 #056522 cMLeft
gene4 darkmagenta cM
DAPI dodgerblue square
protein cornflowerblue exProtein
B black square
gene1 chocolate upArrow
CMA darkgoldenrod1 square

For fixing column names use:

colnames(mydfMarkColorHolo) <- c("markName", "markColor","style") 
# if style column not present it will be filled with "square"

Get marks positions data

Open or write your mark positions in a data.frame. This data.frame has the marks present in all karyotypes with position info.

For holocentrics, position is defined with column markPos, while in monocentrics it is markDistCen.

Column chrRegion can be absent for holocentrics.

# We will use column OTU if data.frame because chromosome size df has it
mydfMarkPosHolo <- read.table(text =
  "          OTU  chrName markName markPos markSize chrRegion
\"Species one\"       4        B      NA       NA        w    # w = whole chromosome mark
\"Species one\"       3     DAPI     2.0      0.5
\"Species one\"       1      45S     2.0      0.5
\"Species one\"       2     protein  3.5      1.5
\"Species one\"       2     gene1    1.0      0.5
\"Species one\"       1     gene2    1.0      0.5
\"Species one\"       4     gene3    3.0      0.5
\"Species one\"       3     gene4    1.0      0.5
\"Species one\"       X      CMA     2.0      0.5
\"Species one\"       X       5S     0.5      0.5
\"Species one\"       X       5S     0.5      0.5",  header = TRUE, stringsAsFactors = FALSE, fill = TRUE)
OTU chrName markName markPos markSize chrRegion
Species one 4 B NA NA w
Species one 3 DAPI 2.0 0.5
Species one 1 45S 2.0 0.5
Species one 2 protein 3.5 1.5
Species one 2 gene1 1.0 0.5
Species one 1 gene2 1.0 0.5
Species one 4 gene3 3.0 0.5
Species one 3 gene4 1.0 0.5
Species one X CMA 2.0 0.5
Species one X 5S 0.5 0.5
Species one X 5S 0.5 0.5

For fixing column names use something like:

colnames(mydfMarkPosHolo)<-c("OTU", "chrName","markName","markPos","markSize") 

Plotting

You can plot without marks (passing only 1st data.frame), but we will use all 4 data.frames created:

# library(idiogramFISH)
# svg("mydfChrSizeHolo.svg",width = 13.5, height = 6 )
# png("mydChrSizeHolo.png", width = 600, height = 300)

par(mar = c(0, 0, 0, 1)) # bottom left top right

plotIdiograms(dfChrSize  = mydfChrSizeHolo,    # data.frame of chr. sizes
  dfMarkColor = mydfMarkColorHolo,  # df of mark style
  dfMarkPos  = mydfMarkPosHolo,     # df of mark positions
  chrSpacing = 1,
  addOTUName = FALSE,           # add OTU names

  xlimLeftMod = 2,              # modify xlim left argument
  ylimTopMod = -1,              # modify ylim top argument
  ylimBotMod = -2               # modify ylim bottom argument
  , rulerPos = 0                # ruler position
  , ruler.tck = -0.01           # ruler ticks size and orient.
  , xPosRulerTitle = 2.6,
  legendWidth = 1               # width of legend
  , legendHeight = .5           # height of legend item
  , xModifier = 50              # separation among chromatids
)

# dev.off() # closes png or svg

It is not mandatory to use dfMarkColor and you can also use the parameter mycolors (optional too), to establish marks’ colors. When using mycolors, colors are assigned depending on the order of marks, i.e.:

unique(dfMarkPosHolo$markName)
# [1] "5S"   "DAPI" "45S"  "CMA"

par(mar = rep(0, 4))

plotIdiograms(dfChrSize = dfChrSizeHolo,  # d.f. of chr. size
  dfMarkPos = dfMarkPosHolo,  # d.f. of marks' positions

  mycolors   = c("red", "dodgerblue", "fdsjkfds", "chartreuse3", "darkgoldenrod1"),  # colors for marks

  addOTUName = FALSE,           # do not add OTU name
  ruler = FALSE,                # do not add ruler
  xlimLeftMod = 1,              # modify left xlim arg.
  xlimRightMod = 3,             # modify right xlim arg.
  ylimBotMod = .2               # modify bottom ylim
  , chromatids = FALSE          # do not show separ. chromatids
)

4.4 ggplot holocentrics

With function mapGGChrMark and the data.frames of chr. (dfChrSizeHolo) and marks’ position (dfMarkPosHolo) for one OTU, you get a list of data.frames for ggplot (Wickham et al., 2020)


chrAndMarksMap <- mapGGChrMark(dfChrSizeHolo, dfMarkPosHolo, chrSpacing = .5)

require(ggplot2)

myColors <- c("chartreuse3", "red", "darkgoldenrod1", "dodgerblue")
names(myColors) <- c("45S", "5S", "CMA", "DAPI")

ggplot() +
  geom_polygon(aes(x = x,
    y = y,
    group = Chr
  ),
  data = chrAndMarksMap$dataChr,
  color = "gray",
  fill = "gray"
  ) +
  geom_polygon(aes(x = x, y = y,
    group = id,
    color = markName,
    fill = markName
  ),
  data = chrAndMarksMap$dataMark
  ) +
  theme_classic() +
  scale_color_manual(
    values = myColors
  ) +
  scale_fill_manual(
    values = myColors
  ) +
  scale_x_continuous(breaks = seq(1, nrow(dfChrSizeHolo), 1)
  ) +
  scale_y_continuous(breaks = seq(0, 5, 0.5)
  ) +
  geom_segment(aes(y = 0, yend = 5, x = -Inf, xend = -Inf)
  ) +
  theme(axis.line   = element_blank(),
    axis.ticks.x = element_blank(),
    axis.title  = element_blank(),
    title      = element_blank()
  )

require(svglite)
ggsave(file = "ggplot.svg", width = 6, height = 4)

0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 1 2 3 4 45S 5S CMA DAPI

4.5 Plot holo. and mono. in the same karyotype

To accomplish this, we will use cenStyle marks in a “holocen.” karyotype. The ruler is continuous as in holocen.

# mark general characteristics' data.frame:

mydfMarkColorHolo2 <- read.table(text =
  "  markName    markColor      style
     5S        red            dots
     45S       chartreuse3    square
     gene2     salmon         downArrow
     gene3     \"#056522\"    cMLeft
     gene4     darkmagenta    cM
     DAPI      dodgerblue     square
     protein   cornflowerblue exProtein
     B         black          square
     gene1     chocolate      upArrow
     CMA       darkgoldenrod1 square
     c45S      chartreuse3    cenStyle    # <- simulate Cen.
     myCen2    red            cenStyle
     myCen     chartreuse2    cenStyle
     constr    NA             cenStyle",  header = TRUE, stringsAsFactors = FALSE, fill = TRUE)


# add new cenStyle marks to data.frame of marks' position, created above

mydfMarkPosHolo2 <- plyr::rbind.fill(mydfMarkPosHolo,
  data.frame(OTU = "Species one",
    chrName = c(1:3, "X"),
    markName = c("c45S", "myCen2", "constr", "myCen"), # <- use new mark
    markPos = c(rep(2.5, 3), 1),
    markSize = NA
  )
)

# png("mydChrSizeHolo.png", width = 600, height = 300)
par(mar = c(0, 0, 0, 1)) # bottom left top right

plotIdiograms(dfChrSize  = mydfChrSizeHolo,     # data.frame of chr. sizes
  dfMarkColor = mydfMarkColorHolo2, # df of mark style
  dfMarkPos = mydfMarkPosHolo2,     # df of mark positions
  addOTUName = FALSE,               # add OTU names

  xlimLeftMod = 2,              # modify xlim left argument
  ylimTopMod = -1,              # modify ylim top argument
  ylimBotMod = -2               # modify ylim bottom argument
  , rulerPos = 0,
  ruler.tck = -0.01,
  xPosRulerTitle = 2.6,
  legendWidth = 1               # width of legend
  , legendHeight = .5           # height of legend item
  , lwd.mimicCen = 2.5          # line width of const. mark
  , pattern = "^c"              # regex pattern to remove from mark names
  , remSimiMarkLeg = TRUE       # remove pseudoduplicated mark names (got equal after pattern removal)
  , bannedMarkName = c("myCen", "myCen2", "B") # hide label
  # ,legend = "inline"           # legends inline
) # ; dev.off() closes png

5 Multiple OTUs


Jupyter interactive version:

Open in ColabOpen in Colab   Github   Raw


5.1 Example with several species (OTUs) - mono.

To illustrate this, we will load some data.frames from the package

  • Chromosome sizes
require(idiogramFISH)
head(bigdfOfChrSize, 15)
OTU chrName shortArmSize longArmSize
Species 1 1 1.5 2.0
Species 1 2 2.0 2.5
Species 1 3 1.0 2.0
Species 2 1 3.0 4.0
Species 2 2 4.0 5.0
Species 2 3 2.0 3.0
Species 2 X 1.0 2.0
Species 2 4 3.0 4.0
Species 3 1 3.2 4.0
Species 3 2 4.5 5.0
Species 3 3 2.0 3.0
Species 3 4 1.5 2.0
Species 3 5 4.8 6.0
Species 3 6 6.1 7.0
Species 4 1 1.5 2.0
  • Mark characteristics, does not require OTU
  • df optional for ver > 1.0.0
data("dfMarkColor")
markName markColor style
5S red dots
45S chartreuse3 square
DAPI blue square
CMA darkgoldenrod1 square
  • Mark position
data("bigdfOfMarks")
OTU chrName markName chrRegion markDistCen markSize
Species 1 1 5S p 0.5 1
Species 1 1 45S q 0.5 1
Species 1 2 45S p 1.0 1
Species 1 3 DAPI q 1.0 1
Species 3 3 5S p 1.0 1
Species 3 3 DAPI q 1.0 1
Species 3 4 45S p NA NA
Species 3 4 DAPI q 1.0 1
Species 3 5 CMA q 2.0 1
Species 3 6 5S q 0.5 1
Species 2 1 DAPI cen NA NA
Species 2 4 CMA cen NA NA

Plotting

# png("bigdfOfChrSize.png", width = 650, height = 1300)
par(mar = c(0, 0, 0, 0))
plotIdiograms(dfChrSize  = bigdfOfChrSize, # chr. sizes
  dfMarkColor = dfMarkColor,  # mark characteristics, optional in dev version. see above.
  dfMarkPos  = bigdfOfMarks,  # mark positions (inc. cen. marks)

  karHeight = 2.5,           # karyotype rel. height
  karHeiSpace = 6,           # karyotype vertical size with spacing
  chrWidth = .35,            # chr. width
  amoSepar = 2,              # Vertical separation of kar. when karSepar = TRUE

  squareness = 4,            # squareness of chr. vertices
  distTextChr = .8,          # distance of chr. to text
  chrIndex = "AR",           # add arm ratio only. For v. >=1.12
  nameChrIndexPos = 3,
  morpho = "Guerra",           # add chr. morphology by Guerra, see above. For v. >=1.12
  indexIdTextSize = .6,        # font size of indices and chr. name
  OTUTextSize = .9,            # font size of OTU names

  markLabelSize = .7,          # font size of legend
  fixCenBorder = TRUE,         # use chrColor as border color of cen. or cen. marks
  legendHeight = 2,            # height of labels

  rulerPos = -1,               # position of ruler
  ruler.tck = -0.004,          # size and orient. of ticks in ruler
  rulerNumberPos = .4,         # position of numbers of ruler
  rulerNumberSize = .4,        # font size of ruler
  xPosRulerTitle = 5,          # ruler units pos.
  rulerTitleSize = .5,         # ruler font size of units (title)

  xlimRightMod = 3,          # modify xlim left argument
  xlimLeftMod = 2,           # modify xlim left argument
  ylimBotMod = 0,            # modify ylim bottom argument
  ylimTopMod = -.3           # modify ylim top argument
)

# dev.off() # for png()

5.2 Example with several species (OTUs) - holo.

To illustrate this, we will load some data.frames from the package

  • Chromosome sizes
data(bigdfChrSizeHolo)
OTU chrName chrSize
species one 1 5.1
species one 2 5.0
species one 3 4.9
species one 4 5.2
species two 1 3.0
species two 2 4.0
species two 3 2.0
species two 4 5.0
species three 1 1.5
species three 2 2.0
species three 3 6.0
species three 4 8.0
  • Mark characteristics, does not require OTU
  • d.f optional for ver. > 1.0.0
data(dfMarkColorIn) 
markName markColor style
5S red dots
45S chartreuse3 square
DAPI blue square
CMA darkgoldenrod1 square
proteinD darkgreen inProtein
  • Mark position
data(bigdfMarkPosHolo2)
OTU chrName markName markPos markSize chrRegion
species two 3 5S 1.0 0.5 NA
species two 3 DAPI 1.5 0.5 NA
species two 1 45S 2.0 0.5 NA
species two 2 DAPI 2.0 0.5 NA
species two 4 CMA 2.0 0.5 NA
species two 4 5S 0.5 0.5 NA
species one 1 proteinD NA NA w
species one 2 proteinD NA NA w
species one 3 proteinD NA NA w
species one 4 proteinD NA NA w
species two 1 proteinD NA NA w
species two 2 proteinD NA NA w
species two 3 proteinD NA NA w
species two 4 proteinD NA NA w
species three 1 proteinD NA NA w
species three 2 proteinD NA NA w
species three 3 proteinD NA NA w
species three 4 proteinD NA NA w

Plotting

library(idiogramFISH)

# fig.width = 6, fig.height = 6
png("bigdfChrSizeHolo.png", width = 600, height = 600)
par(mar = rep(0, 4))

plotIdiograms(dfChrSize = bigdfChrSizeHolo, # chr. size data.frame
  dfMarkColor = dfMarkColorIn,   # df of mark style
  dfMarkPos = bigdfMarkPosHolo2, # df of marks' position

  markDistType = "cen",         # measure towards center of mark
  squareness = 6,               # vertices squareness of chr. and marks

  karHeiSpace = 4,            # karyotype height including spacing
  karSepar = TRUE,            # reduce vertical space among karyotypes
  amoSepar = 1,               # separation among karyotypes
  distTextChr = .5,           # distance text to chr.

  legendWidth = 1             # width of legend labels

  , chrId = "simple",           # numbering of chr., not using "original" name

  indexIdTextSize = .9,         # font size of chr names and indices
  markLabelSize = .9,           # font size of legends

  rulerPos = 0,                 # position of ruler
  rulerNumberSize = .9,         # font size of ruler
  ruler.tck = -.004,            # tick length and orient.
  xPosRulerTitle = 3,           # position of ruler units (title)

  ylimBotMod = .4               # modify ylim bottom argument
  , xModifier = 50              # separation among chromatids
)
dev.off()

6 Changing Units


Jupyter interactive version:

Open in ColabOpen in Colab   Github   Raw


6.1 Using bases instead of micrometers - no. cen.

Create some data in millions of bases:

require(idiogramFISH)
# transform data.frames for simplicity
bigdfChrSizeHoloMb <- bigdfChrSizeHolo # included in idiogramFISH
bigdfChrSizeHoloMb$chrSize <- bigdfChrSizeHoloMb$chrSize * 98000000
bigdfMarkPosHoloMb <- bigdfMarkPosHolo
bigdfMarkPosHoloMb$markPos <- bigdfMarkPosHoloMb$markPos * 98000000
bigdfMarkPosHoloMb$markSize <- bigdfMarkPosHoloMb$markSize * 98000000

Plotting

In the plot length is shown in Mb

png("bigdfChrSizeHolo2.png", width = 700, height = 600)
# par(mar = c(1, 1,1, 1))
par(mar = rep(0, 4))

plotIdiograms(dfChrSize = bigdfChrSizeHoloMb,  # chr. size data.frame
  dfMarkColor = dfMarkColor,       # df of mark style
  dfMarkPos = bigdfMarkPosHoloMb,  # df of mark positions

  markDistType = "cen",            # distance to mark is to its center
  squareness = 4,                  # vertices squareness of chr. and marks
  distTextChr = .5,                # separ. chr. to text

  karHeight = 2,                 # rel. karyotype height
  karHeiSpace = 4,               # karyotype height including spacing
  karSepar = TRUE,               # reduce spacing among karyotypes
  amoSepar = 1,                  # depends on karSepar, amount of sep.

  chrId = "simple",                # chr. names not "original"
  chrSize = TRUE,                  # show chr. size under chr.
  indexIdTextSize = .9,            # font size of chr names and indices
  karIndex = FALSE,                # do not add karyotype asymmetry index

  rulerNumberSize = .9,            # font size of ruler
  rulerPos = 0,                    # position of ruler
  ruler.tck = -.004,               # ruler tick length and orient.
  xPosRulerTitle = 3.5,            # modifies position of ruler title (Mb)

  markLabelSize = .9,              # font size of legend
  legendWidth = 1.2,               # width of legends

  xlimLeftMod = 1,                 # modify left argument of xlim
  ylimBotMod = .4                  # modify bottom argument of ylim
  , chromatids = FALSE             # do not show chromatids
  , OTUfont = 3                    # italics
)
dev.off()

For another example see: https://stackoverflow.com/questions/33727432/how-to-plot-positions-along-a-chromosome-graphic/57153497#57153497

6.2 Using threshold to fix scale

The default value of 35 for threshold may shrink one of the OTUs of this example more than expected. In this case threshold must be bigger.

# fig.width = 7, fig.height = 7
bigdfOfChrSize3_100Mb <- bigdfOfChrSize3Mb
bigdfOfChrSize3_100Mb$chrSize <- bigdfOfChrSize3Mb$chrSize * 33

bigdfOfMarks3_100Mb <- bigdfOfMarks3Mb
bigdfOfMarks3_100Mb$markPos <- bigdfOfMarks3_100Mb$markPos * 33
bigdfOfMarks3_100Mb$markSize <- bigdfOfMarks3_100Mb$markSize * 33

par(mar = rep(0, 4))
plotIdiograms(dfChrSize   = bigdfOfChrSize3_100Mb,  # chr. size data.frame
  dfMarkPos   = bigdfOfMarks3_100Mb,    # mark position df

  chrWidth = .6,              # width of chr.
  chrSpacing = .6,            # space among chr.
  karHeight = 3,              # kar. height without interspace
  karHeiSpace = 5,            # vertical size of karyotype including spacer
  amoSepar = 2,               # separ. among kar.

  indexIdTextSize = .6,       # font size of chr. name and indices
  markLabelSize = .7,         # font size of mark legends
  distTextChr = .65,          # separation among chr. names and indices

  fixCenBorder = TRUE         # use chrColor as border color of cen. or cen. marks
  , legendWidth = 1.5         # legend items width

  , xPosRulerTitle = 3.5      # position of Mb (title) in ruler
  , rulerPos = 0,             # ruler position
  ruler.tck = -0.005,         # ticks of ruler size and orientation
  rulerNumberPos = .7,        # position of numbers in ruler
  rulerNumberSize = .7,       # font size of ruler numbers
  rulerInterval = 1.5,        # ruler interval for micrometeres
  rulerIntervalMb = 50,       # ruler interval for Mb

  ylimBotMod = 0.4,           # modify ylim bottom argument
  ylimTopMod = 0              # modify ylim top argument
  , chromatids = FALSE        # do not show chromatids

  ####  NEW    #####
  , threshold = 90            # this will allow to not to shrink data greater than 350 Mb
)

6.3 Plot data in micrometers and bases

Info in number of bases can be combined in the same plot with info. in micrometers.

Here the new mark style cenStyle is used to add centromeres to “holocen.” (genomes).

To make the rules fit better, having less excess of length over chr., use ceilingFactor.

# fig.width = 10, fig.height = 10
# modify data in millions to hundreds of millions of Mb
bigdfOfChrSize3_100Mb <- bigdfOfChrSize3Mb[1:8, ]
bigdfOfChrSize3_100Mb$chrSize <- bigdfOfChrSize3_100Mb$chrSize * 100

bigdfOfMarks3_100Mb <- bigdfOfMarks3Mb
bigdfOfMarks3_100Mb$markPos <- bigdfOfMarks3_100Mb$markPos * 100
bigdfOfMarks3_100Mb$markSize <- bigdfOfMarks3_100Mb$markSize * 100

# merge data.frames in micrometers and number of bases
mixedThreeSpChrSize <- plyr::rbind.fill(bigdfOfChrSize[1:8, ], bigdfOfChrSize3_100Mb)
# sort by OTU name
mixedThreeSpChrSize <- mixedThreeSpChrSize[order(mixedThreeSpChrSize$OTU), ]

# add cenStyle marks to simulate centromeres in karyo. in Mb (holocen.)
# compare rulers
bigdfSimCenMarks <- bigdfOfChrSize3_100Mb
bigdfSimCenMarks$markPos <- bigdfSimCenMarks$chrSize / 2

bigdfSimCenMarks$markName <- "sim. cen."
bigdfSimCenMarks$chrSize <- NULL

# merge marks in micrometers and bases
mixedThreeSpMarks <- plyr::rbind.fill(bigdfOfMarks, bigdfOfMarks3_100Mb, bigdfSimCenMarks)

# remove cenStyle mark info.
mixedThreeSpMarks <- mixedThreeSpMarks[which(!(mixedThreeSpMarks$OTU %in% "Species 2 genome" &
  mixedThreeSpMarks$chrName %in% c(1, 4) &
  mixedThreeSpMarks$markName %in% "sim. cen.")), ]

# constric. marks
mixedThreeSpMarks[which(mixedThreeSpMarks$OTU %in% "Species 2 genome" &
  mixedThreeSpMarks$chrName %in% c(1, 4)), ]$markName <- c("cDAPI", "cCMA")

# add arrow mark
mixedThreeSpMarks <- dplyr::bind_rows(mixedThreeSpMarks, mixedThreeSpMarks[nrow(mixedThreeSpMarks), ])
mixedThreeSpMarks[nrow(mixedThreeSpMarks), ]$markName <- "S58A"
mixedThreeSpMarks[nrow(mixedThreeSpMarks), ]$markPos <- .7e+08
mixedThreeSpMarks[nrow(mixedThreeSpMarks), ]$markSize <- .7e+08

dfMarkColorAndStyle <- makedfMarkColorMycolors(unique(mixedThreeSpMarks$markName),
  c("red", "chartreuse3", "dodgerblue", "darkgoldenrod1", "dodgerblue", "darkgoldenrod1", "black")
)

# d.f. of marks'styles

dfMarkColorAndStyle$style[5:7] <- "cenStyle"
dfMarkColorAndStyle$markColor[7] <- NA
dfMarkColorAndStyle$style[8] <- "upArrow"

dfMarkColorAndStyle
#    markName      markColor    style
# 1        5S            red     dots
# 2       45S    chartreuse3   square
# 3      DAPI     dodgerblue   square
# 4       CMA darkgoldenrod1   square
# 5     cDAPI     dodgerblue cenStyle
# 6      cCMA darkgoldenrod1 cenStyle
# 7 sim. cen.           <NA> cenStyle
# 8      S58A            red  upArrow

par(mar = rep(0, 4))
plotIdiograms(dfChrSize   = mixedThreeSpChrSize,  # chr. size data.frame
  dfMarkPos   = mixedThreeSpMarks,    # mark position df
  dfMarkColor = dfMarkColorAndStyle,

  chrWidth = .6,              # width of chr.
  chrSpacing = .6,            # space among chr.
  karHeight = 3,              # kar. height without interspace
  karHeiSpace = 5,            # vertical size of karyotype including spacer
  amoSepar = 2,               # separ. among kar.

  indexIdTextSize = .6,       # font size of chr. name and indices
  markLabelSize = .7,         # font size of mark legends
  distTextChr = .65,          # separation among chr. names and indices
  lwd.mimicCen = 1.5,         # constric. line width

  legendWidth = 1.5,          # legend items width
  fixCenBorder = TRUE,        # use chrColor as border color of cen. or cen. marks

  xPosRulerTitle = 3.7,       # position of Mb (title) in ruler
  rulerPos = 0,               # ruler position
  ruler.tck = -0.005,         # ticks of ruler size and orientation
  rulerNumberPos = .7,        # position of numbers in ruler
  rulerNumberSize = .7,       # font size of ruler numbers
  rulerInterval = 1.5,        # ruler interval for micrometeres
  rulerIntervalMb = 150,      # ruler interval for Mb
  ceilingFactor = 1,          # affects rounding for ruler max. value

  ylimBotMod = 0.4,           # modify ylim bottom argument
  ylimTopMod = 0              # modify ylim top argument
  , holocenNotAsChromatids = TRUE # do not use chromatids in holocen.
  , pattern = "^c"             # regex pattern to remove from mark names
  , remSimiMarkLeg = TRUE      # remove pseudoduplicate names arising from pattern removal
)

Let’s explore those data.frames

head(mixedThreeSpChrSize, 6)
OTU chrName shortArmSize longArmSize chrSize
1 Species 1 1 1.5 2.0 NA
2 Species 1 2 2.0 2.5 NA
3 Species 1 3 1.0 2.0 NA
9 Species 1 genome 1 NA NA 3.5e+08
10 Species 1 genome 2 NA NA 4.5e+08
11 Species 1 genome 3 NA NA 2.5e+08
mixedThreeSpMarks[which(mixedThreeSpMarks$OTU %in% c("Species 1","Species 1 genome") ),] 
OTU chrName markName chrRegion markDistCen markSize markPos
1 Species 1 1 5S p 0.5 1 NA
2 Species 1 1 45S q 0.5 1 NA
3 Species 1 2 45S p 1.0 1 NA
4 Species 1 3 DAPI q 1.0 1 NA
13 Species 1 genome 1 5S NA NA 100000000 250000000
14 Species 1 genome 1 45S NA NA 100000000 50000000
15 Species 1 genome 2 45S NA NA 100000000 350000000
16 Species 1 genome 3 DAPI NA NA 100000000 0
25 Species 1 genome 1 sim. cen. NA NA NA 175000000
26 Species 1 genome 2 sim. cen. NA NA NA 225000000
27 Species 1 genome 3 sim. cen. NA NA NA 125000000

6.4 Use cM as units

Info in cM can be combined in the same plot with info. in micrometers.

To make the rules fit better, having less excess of length over chr., use ceilingFactor.

# fig.width = 10, fig.height = 10
# merge data.frames in micrometers and cM
bigdfOfChrSize3cM <- bigdfOfChrSize3Mb[1:8, ]
bigdfOfChrSize3cM$chrSize <- bigdfOfChrSize3cM$chrSize / 100000
mixedThreeSpChrSize2 <- plyr::rbind.fill(bigdfOfChrSize[1:8, ], bigdfOfChrSize3cM)

# sort by OTU name
mixedThreeSpChrSize2 <- mixedThreeSpChrSize2[order(mixedThreeSpChrSize2$OTU), ]

# create data with cM. markSize col. is not necessary because style is cM
bigdfOfMarks3cM <- bigdfOfMarks3Mb
bigdfOfMarks3cM$markPos <- bigdfOfMarks3Mb$markPos / 100000
bigdfOfMarks3cM$markSize <- NA
# As we want only the cM idiograms to be plotted as cM (lines), change mark names
bigdfOfMarks3cM$markName <- paste0("cM", bigdfOfMarks3cM$markName)

# d.f of all marks
mixedThreeSpMarks2 <- plyr::rbind.fill(bigdfOfMarks, bigdfOfMarks3cM)

# create a data.frame with mark characteristics
mixedDfMarkStyle  <- makedfMarkColorMycolors(unique(mixedThreeSpMarks2$markName),
  c("red", "chartreuse3", "dodgerblue", "darkgoldenrod1")
)

# mark names of cM marks with "cM" style (lines): not dots, not squares
mixedDfMarkStyle[which(mixedDfMarkStyle$markName %in%
  grep("cM", mixedDfMarkStyle$markName, value = TRUE)), ]$style <- "cM"

par(mar = rep(0, 4))
plotIdiograms(dfChrSize   = mixedThreeSpChrSize2,  # chr. size data.frame
  dfMarkPos   = mixedThreeSpMarks2,    # mark position data.frame
  dfMarkColor = mixedDfMarkStyle,     # mark style data.frame

  chrWidth = .6,                # width of chr.
  chrSpacing = .7,            # space among chr.

  specialOTUNames = bigdfOfMarks3cM$OTU, # OTUs in this object will have different ruler units
  specialyTitle = "cM",       # ruler title for specialOTUNames
  specialChrWidth = .2,       # modify chr width of OTUs in specialOTUNames
  specialChrSpacing = 1.1,    # modify chr spacing of OTUs in specialOTUNames

  karHeight = 3,              # kar. height without interspace
  karHeiSpace = 6,            # vertical size of karyotype including spacer
  amoSepar = 3,               # separ. among kar.

  chrSize = TRUE,             # show chr. size under chr.
  indexIdTextSize = .6,       # font size of chr. name and indices
  distTextChr = .85,          # separation among chr. names and indices

  protruding = 1,             # extension of cM mark type
  pattern = "cM",             # regex pattern to remove from mark names
  markLabelSize = .7          # font size of mark legends
  , legendWidth = 2           # legend items width
  , fixCenBorder = TRUE       # use chrColor as border color of cen. or cen. marks
  , lwd.cM = 2                # thickness of cM marks
  , holocenNotAsChromatids = TRUE # do not use chromatids in holocen. kar.

  , xPosRulerTitle = 3.2       # position of Mb or cM (title) in ruler
  , rulerPos = 0,              # ruler position
  ruler.tck = -0.005,          # ticks of ruler size and orientation
  rulerNumberPos = .7,         # position of numbers in ruler
  rulerNumberSize = 0.7,       # font size of ruler numbers
  rulerIntervalcM = 12,        # ruler interval for OTU in specialOTUnames and MbThreshold not met
  ceilingFactor = 1,           # affects max. value in ruler. See also rulerInterval

  ylimBotMod = 0.4,           # modify ylim bottom argument
  ylimTopMod = 0              # modify ylim top argument
)

7 GISH


Jupyter interactive version:

Open in ColabOpen in Colab   Github   Raw


7.1 GISH of monocentric chromosomes

You need the data.frame of chr. sizes, and a d.f. of marks

Chr. sizes:

parentalAndHybChrSize
OTU chrName shortArmSize longArmSize
1 Parental 1 1 3.2 4
2 Parental 1 4 1.5 2
3 Parental 1 5 4.8 6
4 Parental 1 6 6.1 7
8 Allopolyploid 1 3.2 4
9 Allopolyploid 2 4.5 5
10 Allopolyploid 3 2.0 3
11 Allopolyploid 4 1.5 2
12 Allopolyploid 5 4.8 6
13 Allopolyploid 6 6.1 7
5 Parental 2 1 3.2 4
6 Parental 2 2 4.5 5
7 Parental 2 3 2.0 3

Marks’ positions data

dfAlloParentMarks
OTU chrName markName chrRegion
1 Allopolyploid 1 Parental 2 qcen
17 Allopolyploid 1 Parental 1 pcen
16 Allopolyploid 1 Parental 1 p
2 Allopolyploid 1 Parental 2 q
4 Allopolyploid 2 Parental 2 w
5 Allopolyploid 3 Parental 2 w
6 Allopolyploid 4 Parental 1 w
7 Allopolyploid 5 Parental 1 w
8 Allopolyploid 6 Parental 1 w
9 Parental 1 6 Parental 1 w
10 Parental 1 5 Parental 1 w
11 Parental 1 1 Parental 1 w
12 Parental 1 4 Parental 1 w
13 Parental 2 2 Parental 2 w
14 Parental 2 1 Parental 2 w
15 Parental 2 3 Parental 2 w

We will use column note to add a note to the right of the karyotype of the OTU (column)

notesdf2<-read.table(text=
"           OTU                note
\"Parental 1\"     \"Parental One\"  
\"Parental 2\"     \"Parental Two\"  
\"Allopolyploid\"  Allopolyploid  ", header = TRUE, stringsAsFactors = FALSE, fill = TRUE)

7.1.1 Plotting

# svg("gish.svg",width = 7, height = 9 )
# png("parentalAndHybChrSize.png", width = 700, height = 900)

# REORDER OTUs

parentalAndHybChrSize$OTU <- factor(parentalAndHybChrSize$OTU, levels = c("Parental 1", "Allopolyploid", "Parental 2"))
parentalAndHybChrSize <- parentalAndHybChrSize[order(parentalAndHybChrSize$OTU), ]


par(mar = rep(0, 4))
plotIdiograms(dfChrSize = parentalAndHybChrSize,  # d.f. of chr. sizes
  dfMarkPos = dfAlloParentMarks, # d.f. of marks' positions
  cenColor  = NULL,              # no cen. color for GISH

  karHeiSpace = 5,               # karyotype height including spacing
  karSepar = FALSE,              # equally sized (height) karyotypes

  legend = ""                    # no legend

  , notes = notesdf2             # data.frame with notes NEW
  # ,OTUasNote = TRUE              # TRY THIS (OTU name to the right)
  , notesTextSize = 1.3,
  notesPosX = 1.5               # space from chr. (right) to note
  , ruler = FALSE,
  moveKarHor = "Allopolyploid"  # OTU to move to the right
  , mkhValue = 7                # amount to move to right
  , anchor = TRUE               # show anchor for moveKarHor OTUs
  , moveAnchorV = 4             # modify anchor Vertical portion position
  , moveAnchorH = -1.5          # modify anchor Horizon. portion position

  , ylimBotMod = 1              # ylim bottom argument mod.
  , xlimRightMod = 4
)

# dev.off()

7.2 GISH of holocentric chromosomes

You need the data.frame of chr. sizes, and a d.f. of marks

Chr. sizes:

parentalAndHybHoloChrSize
OTU chrName chrSize
Parental 1 7 4
Parental 1 4 2
Parental 1 5 6
Parental 1 6 7
Parental 2 1 4
Parental 2 2 5
Parental 2 3 3
Allopolyploid 7 4
Allopolyploid 2 5
Allopolyploid 3 3
Allopolyploid 4 2
Allopolyploid 5 6
Allopolyploid 6 7

Marks’ positions data

dfAlloParentMarksHolo
OTU chrName markName chrRegion
1 Allopolyploid 7 Parental 1 w
4 Allopolyploid 2 Parental 2 w
5 Allopolyploid 3 Parental 2 w
6 Allopolyploid 4 Parental 1 w
7 Allopolyploid 5 Parental 1 w
8 Allopolyploid 6 Parental 1 w
9 Parental 1 6 Parental 1 w
10 Parental 1 5 Parental 1 w
11 Parental 1 7 Parental 1 w
12 Parental 1 4 Parental 1 w
13 Parental 2 2 Parental 2 w
14 Parental 2 1 Parental 2 w
15 Parental 2 3 Parental 2 w

Plotting

# svg("gish.svg",width = 8, height = 7 )
par(mar = c(0, 0, 0, 0))
plotIdiograms(dfChrSize = parentalAndHybHoloChrSize,  # d.f. of chr. sizes
  dfMarkPos = dfAlloParentMarksHolo,      # d.f. of marks' positions
  chrColor  = "gray",        # chr. color
  cenColor  = NULL,            # cen. color when GISH

  karHeight = 3,               # karyotype height without spacing
  karHeiSpace = 5,             # karyotype height including spacing
  distTextChr = 0.8            # separation among chr. and text

  , ruler = FALSE              # no ruler
  , legend = ""                # no legend

  , xlimRightMod = 0           # xlim right arg. modif.
  , xModifier = 100            # separ. among chromatids
)

# dev.off()

7.3 GISH of Citrus as Yasuda et al. (2010)

For more details on the use of Citrus functions go to chapter Citrus

Parental C. schweinfurthii: 14D + 4F (using Guerra nomenclature).

{
  #
  # c. schweinfurthii chr sizes d.f.
  #

  cschweinformula <- "14D + 4F"
  require(idiogramFISH)

  citrusschwein <- citrusSize(D = 14,
    F = 4,
    OTU = "C. schweinfurthii",
    longArm = 1.2)

  #
  # c. schweinfurthii CMA and GISH marks
  #

  citrusschweinMarkPosDF <- citrusMarkPos(citrusschwein)

  #
  #   data.frame of genomic marks
  #
  citrusschweinMarkPosDF2 <- data.frame(chrName = c(paste0("D_", 1:7), paste0("F_", 1:2)),
    chrRegion = "w",
    markName = "schweingenome",
    OTU = unique(citrusschwein$OTU)
  )

  #
  #   merge marks pos.
  #

  citrusschweinMarkPosDF <- dplyr::bind_rows(citrusschweinMarkPosDF2, citrusschweinMarkPosDF)

  #
  #   Inversion of some chr. (D marks up)
  #

  csSwap <- swapChrRegionDfSizeAndMarks(citrusschwein, citrusschweinMarkPosDF, c(paste0("D_", 1:14)))
  citrusschwein         <- csSwap$dfChrSize
  citrusschweinMarkPosDF <- csSwap$dfMarkPos

  #
  #   mark style
  #

  unique(citrusschweinMarkPosDF$markName)
  {
    markStyleschweinDF   <- makedfMarkColorMycolors(
      unique(citrusschweinMarkPosDF$markName), c("chartreuse3", "darkgoldenrod1"))
  }

  #
  #   d.f. of notes
  #

  leftNotesschwein  <- data.frame(OTU = unique(citrusschwein$OTU), note = paste0("Female gamete: 7D + 2E"))
  leftNotesschweinUp <- data.frame(OTU = unique(citrusschwein$OTU), note = paste0(unique(citrusschwein$OTU), " (", cschweinformula, ")"))
  notesschwein <- data.frame(OTU = unique(citrusschwein$OTU), note = "Yasuda et al. (2010)")
}


Parental ‘Nanpu’ tangor

{

  cnanpuformula <- "1A + 4C + 5D + 8F" # Guerra nom.

  #
  # 'Nanpu' tangor chr. sizes
  #

  citrusnanpu <- citrusSize(A = 1, C = 4, D = 5, F = 8 #
    , OTU = "nanpu tangor",
    longArm = 1.2)
  #
  # c. nanpu CMA marks
  #

  citrusnanpuMarkPosDF <- citrusMarkPos(citrusnanpu)

  #
  #   d.f. of genomic marks
  #

  citrusnanpuMarkPosDF2 <- data.frame(chrName = c("A", "C_1", paste0("D_", 1:4), paste0("F_", 1:3)),
    chrRegion = "w",
    markName = "nanpugenome",
    OTU = unique(citrusnanpu$OTU)
  )

  #
  #   merge marks pos.
  #

  citrusnanpuMarkPosDF <- dplyr::bind_rows(citrusnanpuMarkPosDF2, citrusnanpuMarkPosDF)

  #
  #   mark style d.f.
  #

  unique(citrusnanpuMarkPosDF$markName)
  {
    markStylenanpuDF   <- makedfMarkColorMycolors(
      unique(citrusnanpuMarkPosDF$markName), c("chocolate", "darkgoldenrod1"))
  }

  #
  #   invert some chr.
  #

  csSwap <- swapChrRegionDfSizeAndMarks(citrusnanpu, citrusnanpuMarkPosDF, c(paste0("D_", 1:5)))
  citrusnanpu          <- csSwap$dfChrSize
  citrusnanpuMarkPosDF <- csSwap$dfMarkPos

  #
  #   notes data.frames
  #

  leftNotesnanpu  <- data.frame(OTU = unique(citrusnanpu$OTU), note = paste0("Male gamete: 1A + 1C + 4D + 3E"))
  leftNotesnanpuUp <- data.frame(OTU = unique(citrusnanpu$OTU), note = paste0("'Nanpu' tangor (", cnanpuformula, ")"))

  notesnanpu <- data.frame(OTU = unique(citrusnanpu$OTU), note = "Yasuda et al. (2010)")

}


Merge data.frames from parentals

{
  bothParentalsChr   <- dplyr::bind_rows(citrusnanpu, citrusschwein)

  bothParentalsMarks <- dplyr::bind_rows(citrusschweinMarkPosDF, citrusnanpuMarkPosDF)

  bothPmarkStyle     <- unique(dplyr::bind_rows(markStyleschweinDF, markStylenanpuDF))

  bothPleftNotesUp   <- dplyr::bind_rows(leftNotesschweinUp, leftNotesnanpuUp)

  bothPleftNotes     <- dplyr::bind_rows(leftNotesschwein, leftNotesnanpu)
}


data.frames of the hybrid

{
  cschnanpuformula <- "1A + 1C + 11D + 5F"

  require(idiogramFISH)

  #
  #   hybrid chr. size
  #

  citrusschnanpu <- citrusSize(A = 1, C = 1, D = 11, F = 5 #
    , OTU = "schweinfurthii + nanpu",
    longArm = 1.2)
  #
  # hybrid CMA marks
  #

  citrusschnanpuMarkPosDF <- citrusMarkPos(citrusschnanpu)

  #
  #    invert some chr.
  #

  csSwap <- swapChrRegionDfSizeAndMarks(citrusschnanpu, citrusschnanpuMarkPosDF, c(paste0("D_", 1:11)))
  citrusschnanpu         <- csSwap$dfChrSize
  citrusschnanpuMarkPosDF <- csSwap$dfMarkPos

  #
  #   d.f. of gish marks
  #

  citrusschnanpuMarkPosDF2 <- data.frame(chrName = c(paste0("D_", 5:11), paste0("F_", 1:2)),
    chrRegion = "w",
    markName = "schweingenome",
    OTU = unique(citrusschnanpu$OTU)
  )

  citrusschnanpuMarkPosDF3 <- data.frame(chrName = c("A", "C", paste0("D_", 1:4), paste0("F_", 3:5)),
    chrRegion = "w",
    markName = "nanpugenome",
    OTU = unique(citrusschnanpu$OTU)
  )

  #
  #   merge marks
  #

  citrusschnanpuMarkPosDF <- dplyr::bind_rows(citrusschnanpuMarkPosDF2, citrusschnanpuMarkPosDF3, citrusschnanpuMarkPosDF)

  #
  #   style of marks d.f.
  #

  unique(citrusschnanpuMarkPosDF$markName)
  {
    markStyleschnanpuDF   <- makedfMarkColorMycolors(
      unique(citrusschnanpuMarkPosDF$markName), c("chartreuse3", "chocolate", "darkgoldenrod1"))
  }

  #
  #   notes for hybrid
  #
  # italics!       #  rest: \"                 to                           \"
  name <-  paste0("italic('C. schweinfurthii'),      \" × 'Nanpu' tangor (CN3) (", cschnanpuformula, ")\"")
  # to parse italics, use parseStr2lang = TRUE

  leftNotesschnanpuUp <- data.frame(OTU = unique(citrusschnanpu$OTU), note = name)
  notesschnanpu       <- data.frame(OTU = unique(citrusschnanpu$OTU), note = "'Yasuda et al. (2010)'")
}


Plot

#
#   plot of parentals only
#

{
  par(mar = rep(0, 4), oma = rep(0, 4))
  plotIdiograms(callPlot = TRUE,
    dfChrSize = bothParentalsChr,   # chr. size data.frame
    dfMarkPos = bothParentalsMarks, # mark position data.frame
    dfMarkColor = bothPmarkStyle,   # mark style d.f.

    orderChr = "original"      # order of chr. as in d.f.

    , chrWidth = .5            # chr. width
    , chrSpacing = .5          # separ. among chr.
    , karHeight = 4            # kar. height
    , karHeiSpace = 5          # anchor height

    , chromatids = FALSE       # don't use chromatids
    , chrColor = "white"     # chr. color

    , ruler = FALSE            # don't use ruler
    , chrId = ""               # don't use chr. name
    , chrIndex = ""            # don't use chr. indices
    , morpho = ""              # don't use morphology
    , karIndex = FALSE         # don't use kar. indices
    , colorBorderMark = "black" # color of border of marks
    , addOTUName = FALSE       # do not add OTU names

    , lwd.chr = 1.6            # border width
    , lwd.marks = 1            # border width marks
    , gishCenBorder = TRUE     # cen. border of gish as mark color
    , hideCenLines = 1.75      # hide cen. border

    , legend = ""              # no legend for marks

    , leftNotes  =  bothPleftNotes    # data.frame with left notes
    , leftNotesUp =  bothPleftNotesUp # data.frame with Up left notes
    , leftNoteFontUp = 3      # italics

    , leftNotesTextSize = 1.3     # font size of notes
    , leftNotesUpTextSize = 1.3   # font size of notes

    , leftNotesPosX = 0      # horizontal pos. of left notes
    , leftNotesPosY = 0      # vertical pos. of left down notes

    , leftNotesUpPosX = 0    # horizontal pos. of left up notes
    , leftNotesUpPosY = 2    # vertical pos. of left up notes

    , verticalPlot = FALSE     # horizontal plot
    , karSpaceHor = 3          # horizontal spacing among kar.

    , karAnchorLeft = "C. schweinfurthii" # anchor to the left of
    , anchor = TRUE            # add anchor

    , ylimBotMod = 1         # modify ylim bottom argument
    , ylimTopMod = 0         # modify ylim top argument
    , xlimLeftMod = 0        # modify left xlim
    , xlimRightMod = 2       # modify right xlim

  )
}

#  add plot of hybrid over parents plot

{
  plotIdiograms(callPlot = FALSE,                     # plot over previous plot
    dfChrSize = citrusschnanpu,          # chr. size data.frame
    dfMarkPos = citrusschnanpuMarkPosDF, # mark position data.frame
    dfMarkColor = markStyleschnanpuDF,    # mark style d.f.

    orderChr = "original",  # order of chr. as in d.f.

    chrWidth = .5,          # chr. width
    chrSpacing = .5,        # separ. among chr.
    karHeight = 4           # kar. height
    , chromatids = FALSE    # don't use chromatids
    , chrColor = "white"    # chr. color

    , ruler = FALSE            # don't use ruler
    , chrId = ""               # don't use chr. name
    , chrIndex = ""            # don't use chr. indices
    , morpho = ""              # don't use morphology
    , karIndex = FALSE         # don't use kar. indices
    , colorBorderMark = "black" # color of border of marks
    , addOTUName = FALSE       # don't add OTU name

    , lwd.chr = 1.6            # border width
    , lwd.marks = 1            # border width marks

    , leftNotesUp = leftNotesschnanpuUp # up notes: name of hybrid
    , parseStr2lang = TRUE   # for italics, see notes data.frame
    , notesTextSize = 1.3    # font size of notes
    , leftNotesUpTextSize = 1.3   # font size of notes

    , leftNotesPosX = 0      # horizontal pos. of notes
    , leftNotesUpPosY = 2    # vertical pos. left up notes
    , notes = notesschnanpu  # right notes - authors
    , notesPosX = 3          # notes hor. pos

    , ylimBotMod = 1         # modify ylim bottom argument
    , ylimTopMod = -5        # modify ylim top argument
    , xlimLeftMod = 0        # modify left xlim
    , xlimRightMod = 2       # modify right xlim

    , gishCenBorder = TRUE     # cen. border as mark color
    , legend = ""              # no legend for marks
    , hideCenLines = 1.75      # hide cen. lines
    , moveAllKarValueHor = 9.5 # move kar. to right
    , moveAllKarValueY = -10   # move kar. down
  )
} # hybrid

8 Groups


Jupyter interactive version:

Open in ColabOpen in Colab   Github   Raw


8.1 monocentrics

Adding the column group

Open your chromosome data - Chr. size - as data.frame and add column

# Example data.frame written in R, use
dfwithgroups <- read.table(text = "
      chrName shortArmSize longArmSize group
1        1            3           5     1
2        1            3.2         5.5   1
3        1            3.5         4.8   1
4        4            1           3     NA
5        5            3           5     NA
6        X            4           6     NA", header = TRUE, stringsAsFactors = FALSE)
chrName shortArmSize longArmSize group
1 3.0 5.0 1
1 3.2 5.5 1
1 3.5 4.8 1
4 1.0 3.0 NA
5 3.0 5.0 NA
X 4.0 6.0 NA

Heteromorphic pairs

It can be used to plot heteromorphic pairs, see pair 1
dfwithHetero <- read.table(text = "
       chrName shortArmSize longArmSize group
1        1A           3           5     1
2        1B           3           5     1
4        2            1           3     NA
5        3            3           5     NA
6        4            4           6     NA", header = TRUE, stringsAsFactors = FALSE)
chrName shortArmSize longArmSize group
1 1A 3 5 1
2 1B 3 5 1
4 2 1 3 NA
5 3 3 5 NA
6 4 4 6 NA
Open or write your mark positions as a data.frame. This data.frame has the marks present in all karyotypes with position info.
dfOfMarksHetero <- read.table(text =
  "     chrName markName chrRegion markSize markDistCen
1       1A       5S       p        1         0.9
2       1B      45S       p        1         0.9
3       2       CMA       q        1         1.0
4       3      DAPI       q        1         1.0", header = TRUE, stringsAsFactors = FALSE)
chrName markName chrRegion markSize markDistCen
1A 5S p 1 0.9
1B 45S p 1 0.9
2 CMA q 1 1.0
3 DAPI q 1 1.0

Plot

require(idiogramFISH)
# svg("dfwithHetero.svg",width = 13.5, height = 8 )
par(mar = rep(0, 4))

dfwithHetero$OTU <- "hetero"
dfwithgroups$OTU <- "first"
both <- plyr::rbind.fill(dfwithHetero, dfwithgroups)
dfOfMarksHetero$OTU <- "hetero"
plotIdiograms(dfChrSize = both,    # chr. sizes
  dfMarkPos = dfOfMarksHetero, # position of marks
  karHeiSpace = 4,

  chrId = "original",        # chr. name in df.
  chrIndex = "",             # do not add chr. indices
  morpho = "",               # do not add chr. morphologies
  karIndex = FALSE,          # do not add karyotype indices
  distTextChr = .8,          # distance from text to chr.

  markDistType = "cen",      # mark position measured to center of mark
  orderChr = "name",         # order chr. by name

  ruler = FALSE              # do not plot ruler

  , ylimBotMod = 1           # modify ylim bottom argument
  , legendWidth = 1          # width of legend
)

# dev.off()

8.2 Holocentrics

Let’s modify some data.frames to add a group

data("dfChrSizeHolo")
data("dfMarkPosHolo")
dfMarkPosHoloHetero <- dfMarkPosHolo
dfMarkPosHoloHetero$chrName <- c(3, 3, "1A", 2, "1B", "1B")
dfMarkPosHoloHetero$OTU <- "heteromorphic"

dfChrSizeHoloHetero <- dfChrSizeHolo
dfChrSizeHoloHetero$chrName <- c("1A", "1B", 2, 3)
dfChrSizeHoloHetero$OTU <- "heteromorphic"

# Adding the group column
dfChrSizeHoloHetero$group <- c(1, 1, NA, NA)

Creating a new data.frame for holocentrics

dfChrSizeHoloGroup <- data.frame(OTU = "Species name",
  chrName = c(1, 1, 1, 1, 2, 3, 4),
  chrSize = c(3.1, 3.2, 3.3, 3.4, 4, 5, 6),
  group = c(1, 1, 1, 1, NA, NA, NA)
)
OTU chrName chrSize group
Species name 1 3.1 1
Species name 1 3.2 1
Species name 1 3.3 1
Species name 1 3.4 1
Species name 2 4.0 NA
Species name 3 5.0 NA
Species name 4 6.0 NA
par(mar = rep(0, 4))
mergedChrSize <- plyr::rbind.fill(dfChrSizeHoloGroup, dfChrSizeHoloHetero)

plotIdiograms(dfChrSize = mergedChrSize,      # data.frame of chr. sizes
  dfMarkPos = dfMarkPosHoloHetero, # d.f. of marks
  orderChr = "name",            # order chr. by name
  karIndex = FALSE,             # do not add karyotype indices
  addOTUName = TRUE,            # add OTU name
  karHeiSpace = 4,              # height of kar. with spacing

  ruler = FALSE,                  # no ruler

  xlimLeftMod = -1,               # modify left argument of xlim
  xlimRightMod = 0,               # modify right argument of xlim
  ylimBotMod = 1.3                # modify bottom argument of ylim
  , xModifier = 100               # separ. among chromatids
)

9 Circular Plots


Jupyter interactive version:

Open in ColabOpen in Colab   Github   Raw


visit gitlab for installation instructions https://gitlab.com/ferroao/idiogramFISH

9.1 Example with monocen. and holocen.

{
  require(idiogramFISH)
  require(plyr)
  dfOfChrSize$OTU <- "Species mono"
  dfChrSizeHolo$OTU <- "Species holo"

  monoholoCS <- plyr::rbind.fill(dfOfChrSize, dfChrSizeHolo)

  dfOfMarks2$OTU <- "Species mono"
  dfMarkPosHolo$OTU <- "Species holo"

  monoholoMarks <- plyr::rbind.fill(dfOfMarks2, dfMarkPosHolo)
  monoholoMarks[which(monoholoMarks$markName == "5S"), ]$markSize <- .5

  monoholoMarks[10, ]$markName <- "prot"
  monoholoMarks[10, ]$markSize <- 1
  dfMarkColor <- rbind(dfMarkColor, c("prot", "black", "exProtein"))
}

plotIdiograms(dfChrSize  = monoholoCS,   # data.frame of chr. size
  dfMarkColor = dfMarkColor,  # df of mark style
  dfMarkPos = monoholoMarks,  # df of mark positions, includes cen. marks

  squareness = 5,             # vertices squareness
  addOTUName = TRUE,          # add OTU names
  distTextChr = .5,           # separ. among chr. and text and among chr. name and indices

  chrId = "original",         # use original name of chr.
  OTUTextSize = .7,           # size of OTU name

  legendHeight = 1,           # height of legend labels
  legendWidth = 1,            # width of legend labels
  # ,legend = "inline"
  fixCenBorder = TRUE,        # use chrColor as border color of cen. or cen. marks

  xlimLeftMod = 1,            # modify xlim left argument of plot
  xlimRightMod = 2,           # modify xlim right argument of plot
  ylimBotMod = .2             # modify ylim bottom argument of plot

  , useOneDot = FALSE

  # GRAPHICAL PARAMETERS FOR CIRCULAR PLOT

  , circularPlot = TRUE       # circularPlot
  , shrinkFactor = .9         # percentage 1 = 100% of circle with chr.
  , circleCenter = 3          # X coordinate of circleCenter (affects legend pos.)
  , chrLabelSpacing = .9      # chr. names spacing

  , OTUsrt = 0                # angle for OTU name (or number)
  , OTUplacing = "number"     # Use number and legend instead of name. See OTUcentered
  , OTUjustif = 0             # OTU names justif. left.
  , OTULabelSpacerx = -0.5    # modify position of OTU label, when OTUplacing = "number" or "simple"
  , OTUlegendHeight = 1.5     # space among OTU names when in legend - OTUplacing
  , separFactor = 0.75
)

9.2 Recreating circular karyotype of (Golczyk et al., 2005)

# First swap short and long arms to show the same rotation of the article

listradfs <- swapChrRegionDfSizeAndMarks(traspadf, traspaMarks, c("3", "6", "7", "9", "12"))

# Create marks' characteristics

dfMarkColor5S25S <- read.table(text = "    markName markColor  style
        5S       black dots
       25S       white dots",  header = TRUE, stringsAsFactors = FALSE, fill = TRUE)

plotIdiograms(dfChrSize = listradfs$dfChrSize,  # d.f. of chr. sizes
  dfMarkPos = listradfs$dfMarkPos,  # d.f. of marks' positions
  dfMarkColor = dfMarkColor5S25S,   # d.f. of mark characteristics
  cenColor  = "black",            # cen. color
  squareness = 5,                   # corner squareness
  chrWidth = 1,                     # chr. width
  orderChr = "name"                 # order chr. by name

  , addOTUName = FALSE               # do not add OTU name
  , legendHeight = 3                 # labels separ. y axis

  # circular plot parameters
  , circularPlot = TRUE,
  radius = 5                         # basic radius
  , useOneDot = FALSE                # use two dots in dot marks
  , chrLabelSpacing = 1              # chr. name spacing
  , rotation = 0.1                   # anti-clockwise start site in x*pi radians, from top (0)
  , shrinkFactor = .95               # % of circle use
)

9.3 Plasmid data from genBank

Using upArrow and downArrow styles, clockwise and anti-clockwise, respectively.


# data from: https://www.ncbi.nlm.nih.gov/nuccore/NZ_CP009939.1

# install.packages("rentrez")
library(rentrez)
# search string
bcereus <- "Bacillus cereus strain 03BB87 plasmid pBCN, complete sequence"
bcereus_search <- rentrez::entrez_search(db = "nuccore", term = bcereus)
# get summaries
esummaries <- rentrez::entrez_summary(db = "nuccore", id = bcereus_search$ids)

# download plasmid data
# From the entrez formats:
# https://www.ncbi.nlm.nih.gov/books/NBK25499/table/chapter4.T._valid_values_of__retmode_and/
# idiogramFISH can read only:
rentrezDownloadPlas  <- rentrez::entrez_fetch(db = "nuccore",
  id = bcereus_search$ids[1],
  rettype = "gbwithparts",
  retmode = "text")

mylist <- genBankReadIF(rentrezDownloadPlas)

# data.frames in mylist
names(mylist)
# [1] "gbdfMain"         "gbdfAssemblyMeta" "source"           "gene"            
# [5] "CDS"

# mylist$source
# View(mylist$gbdfMain)
# View(mylist$gbdfAssemblyMeta)
# mylist$gbdfAnnoMeta
# View(mylist$CDS)
# View(mylist$gene)

# Authors of plasmid sequence
paste(mylist$gbdfMain[which(mylist$gbdfMain$field == "AUTHORS"), ][1, 2])
# [1] "Johnson,S.L., Minogue,T.D., Teshima,H., Davenport,K.W., Shea,A.A.,; Miner,H.L., Wolcott,M.J. and Chain,P.S."

# create plasmid size data data.frame
{
  myPlasmiddf <- data.frame(chrName = 1, chrSize = mylist$source$end)
  myPlasmiddf$OTU <- mylist$gbdfMain[which(mylist$gbdfMain$field == "DEFINITION"), ]$value
  myPlasmiddf$OTU <- gsub(", complete sequence.", "", myPlasmiddf$OTU)

  # Creating mark info data.frame

  mylistSel <- mylist[which(names(mylist) %in% "gene")]
  mylistSelDF <- dplyr::bind_rows(mylistSel, .id = "feature")

  mylistSelDF$markPos <- pmin(as.numeric(mylistSelDF$begin), as.numeric(mylistSelDF$end))
  mylistSelDF$markSize <- abs(as.numeric(mylistSelDF$end) - as.numeric(mylistSelDF$begin))
  mylistSelDF$markName <- mylistSelDF$locus_tag

  # orientation of arrows
  mylistSelDF$style <- ifelse(mylistSelDF$isComplement, "downArrow", "upArrow")

  # Replace codes with names
  mylistSelDF[which(!is.na(mylistSelDF$gene)), ]$markName <-
    mylistSelDF[which(!is.na(mylistSelDF$gene)), ]$gene

  # subset columns
  marksDfPlas <- mylistSelDF[, c("markName", "markPos", "markSize", "style"), ]

  # add OTU name
  marksDfPlas$OTU <- myPlasmiddf$OTU

  # add mandatory column
  marksDfPlas$chrName <- myPlasmiddf$chrName

  # organize inner arrows (downArrow) in two columns avoiding overlap

  protVal <- .5     # this values (and others) must be the same
  circVal <- TRUE   # in plotIdiograms function
  rotaVal <- 0

  marksDfPlasCols <- namesToColumns(marksDfPlas, myPlasmiddf,
    markType = c("downArrow"),
    amountofSpaces = 10, colNumber = 2,
    protrudingInt = 1.3, protruding = protVal,
    circularPlot = circVal,
    rotation = rotaVal
  )


  # add marker for start pos.
  colnames(marksDfPlasCols)
  marksDfPlasCols <- rbind(marksDfPlasCols, c(paste0("START", paste0(rep(" ", 0), collapse = "")), 1, NA, "square", myPlasmiddf$OTU, 1, NA))

  # create mark general data data.frame
  markStyle   <- makedfMarkColorMycolors(
    unique(marksDfPlasCols$markName), c("black", "forestgreen", "cornflowerblue"))

  # arrows
  markStyle$style      <- marksDfPlasCols$style[match(markStyle$markName, marksDfPlasCols$markName)]
  markStyle$protruding <- marksDfPlasCols$protruding[match(markStyle$markName, marksDfPlasCols$markName)]

  # prefix to remove from marks
  mypattern <- sub("([[:alnum:]]+_).*", "\\1", trimws(marksDfPlas$markName[1]))
}
library(idiogramFISH)
par(mar = rep(0, 4), oma = rep(0, 4))

plotIdiograms(dfChrSize = myPlasmiddf,  # plasmid size d.f.
  dfMarkPos = marksDfPlasCols,  # mark pos d.f.
  dfMarkColor = markStyle,      # mark style d.f.

  chromatids = FALSE,

  squareness = 21,          # corners not rounded
  chrWidth = 0.5,           # chr. width
  chrId = "",               # no chr. name

  markLabelSize = .7,       # font size of labels
  pattern = mypattern,      # remove pattern from mark names
  cMBeginCenter = TRUE,
  legend = "inline",
  protruding = protVal,

  ylimBotMod = 0,           # modify plot size
  ylimTopMod = 0,
  xlimLeftMod = 2,

  # circular params.
  circularPlot = circVal,   # circular
  rotation = rotaVal,       # begin plasmid in top

  radius = 2.5,
  shrinkFactor = 1,         # use 100% of circle
  labelSpacing = 1.7,       # label spacing from chr.
  labelOutwards = TRUE,     # label projected based on mark angle

  OTUjustif = 0.5,          # OTU name justif. centered.
  OTUplacing = "simple"     # plasmid name place. See OTUcentered
  , OTUTextSize = .8        # font size of OTU name
)

9.4 Prokaryote chromosome from genBank

# Option 1: Download prokaryote genome data from:
# https://www.ncbi.nlm.nih.gov/nuccore/NC_014248.1
# Choose Customize View -> Basic Features -> genes, CDS
# Send To -> File -> Create File

# Use your file name:
dataChr.gb <- "nostoc.gb" # 5 Mbytes

# Option 2: Download with rentrez package

library(rentrez)
# search string
nostoc <- "'Nostoc azollae' 0708, complete"
nostoc_search <- rentrez::entrez_search(db = "nuccore", term = nostoc)
# get summaries
esummariesNostoc <- rentrez::entrez_summary(db = "nuccore", id = nostoc_search$ids)
# select only perfect matches
select <- numeric()
for (i in seq_along(esummariesNostoc)) {
  print(esummariesNostoc[[i]]$title)
  if (esummariesNostoc[[i]]$title %in% grep(nostoc, esummariesNostoc[[i]]$title, value = TRUE)) {
    select <- c(select, i)
  }
}
select
# 3 8

# download chr. data
dataChr.gb  <- rentrez::entrez_fetch(db = "nuccore",
  id = nostoc_search$ids[select][1],
  rettype = "gbwithparts",
  retmode = "text")
# START:
library(idiogramFISH)
mylistChr <- genBankReadIF(dataChr.gb) # 9 seconds
names(mylistChr)
# "gbdfMain"     "gbdfAnnoMeta" "source"       "gene"         "CDS"          "tRNA"
# "regulatory"   "ncRNA"        "rRNA"         "misc_feature" "tmRNA"

# Authors of sequence
paste(mylistChr$gbdfMain[which(mylistChr$gbdfMain$field == "AUTHORS"), ][1, 2])
# [1] "Ran, L., Larsson, J., Vigil-Stenman, T., Nylander, J.A., Ininbergs, K.,;
# Zheng, W.W., Lapidus, A., Lowry, S., Haselkorn, R. and Bergman, B."

# create chr. size data data.frame
# columns chrName and chrSize
myProkaryotedf <- data.frame(chrName = 1, chrSize = mylistChr$source$end)
# column with OTU name
myProkaryotedf$OTU <- mylistChr$gbdfMain[which(mylistChr$gbdfMain$field == "DEFINITION"), ]$value
myProkaryotedf$OTU <- gsub(", complete genome.", "", myProkaryotedf$OTU)

# Creating mark info data.frame excluding some features
mylistChrSel  <- mylistChr[which(names(mylistChr) %in%
  setdiff(names(mylistChr), c("gbdfMain", "gbdfAnnoMeta", "source", "CDS")))]
# or:
# mylistSel<- mylistChr[which(names(mylistChr) %in% "CDS")]

# transform list into data.frame
mylistChrDF <- dplyr::bind_rows(mylistChrSel, .id = "feature")
# add necessary columns
mylistChrDF$markPos <- pmin(as.numeric(mylistChrDF$begin), as.numeric(mylistChrDF$end))
mylistChrDF$markSize <- abs(as.numeric(mylistChrDF$end) - as.numeric(mylistChrDF$begin))
mylistChrDF$markName <- mylistChrDF$locus_tag

# Replace codes with genes, and replace NAs in markNames (locus_tag)
mylistChrDF[which(!is.na(mylistChrDF$gene)), ]$markName <-
  mylistChrDF[which(!is.na(mylistChrDF$gene)), ]$gene

mylistChrDF[which(!is.na(mylistChrDF$regulatory_class)), ]$markName <-
  mylistChrDF[which(!is.na(mylistChrDF$regulatory_class)), ]$regulatory_class

# make unique names, otherwise some marks may share style and color
mylistChrDF$markName <- make.uniqueIF(mylistChrDF$markName)

# when no markName and note available:
mylistChrDF[which(is.na(mylistChrDF$markName)), ]$markName <-
  sub("([[:alpha:] ]+);.*", "\\1", mylistChrDF[which(is.na(mylistChrDF$markName)), ]$note)

# orientation of arrows
mylistChrDF$style <- ifelse(mylistChrDF$isComplement, "downArrow", "upArrow")

# select main columns for data.frame of marks' positions
marksDfChr <- mylistChrDF[, c("markName", "markPos", "markSize", "feature", "isJoin", "style"), ]

marksDfChr$OTU <- myProkaryotedf$OTU
# add mandatory column
marksDfChr$chrName <- myProkaryotedf$chrName

# Organize mark names in columns to avoid overlap
rotaVal <- 0
marksDfChrCols <- namesToColumns(marksDfChr, myProkaryotedf,
  markType = c("downArrow", "upArrow"),
  amountofSpaces = 13, colNumber = 4,
  protrudingInt = 0.5,
  rotation = rotaVal)

{
  # add marker for start pos.
  colnames(marksDfChrCols)
  marksDfChrCols <- rbind(marksDfChrCols,
    c("                                                           START", 1, NA,
      "start", FALSE, "square", myProkaryotedf$OTU, 1, NA)
  )

  # unique(marksDfChrCols$markName)

  # create mark general data data.frame
  markStyleNostoc   <- makedfMarkColorMycolors(
    unique(marksDfChrCols$markName), c("black", "forestgreen", "cornflowerblue"))

  unique(marksDfChrCols$feature)
  # [1] "gene"         "tRNA"         "regulatory"   "ncRNA"        "rRNA"       "tmRNA"        "start"
  unique(marksDfChrCols$isJoin)
  # [1] "FALSE"

  # change some colors depending on feature
  markStyleNostoc[which(markStyleNostoc$markName %in%
    marksDfChrCols[which(marksDfChrCols$feature %in% c("tRNA", "tmRNA")), ]$markName
  ), ]$markColor <- "magenta"

  markStyleNostoc[which(markStyleNostoc$markName %in%
    marksDfChrCols[which(marksDfChrCols$feature %in% c("regulatory", "ncRNA")), ]$markName
  ), ]$markColor <- "tomato3"

  markStyleNostoc[which(markStyleNostoc$markName %in%
    marksDfChrCols[which(marksDfChrCols$feature %in% "rRNA"), ]$markName
  ), ]$markColor <- "red2"

  markStyleNostoc[which(markStyleNostoc$markName %in%
    marksDfChrCols[which(marksDfChrCols$feature %in% c("misc_binding", "misc_feature")), ]$markName
  ), ]$markColor <- "lightsalmon"

  # or:
  # When isJoin is TRUE (CDS feature included)
  # markStyleNostoc[which(markStyleNostoc$markName %in%
  #                   marksDfChrCols[which(marksDfChrCols$isJoin==TRUE),]$markName
  # ),]$markColor<-"red"

  # arrows info. to d.f. of charac.
  markStyleNostoc$style      <- marksDfChrCols$style[match(markStyleNostoc$markName, marksDfChrCols$markName)]
  markStyleNostoc$protruding <- marksDfChrCols$protruding[match(markStyleNostoc$markName, marksDfChrCols$markName)]

  mypattern <- sub("([[:alnum:]]+_).*", "\\1", trimws(marksDfChrCols$markName[1]))
}

png("NOSTOC.png", width = 2795, height = 2795) # 2.7 Mb increase size to increase resolution
# pdf("NOSTOC.pdf",   width = 2795/80,  height = 2795/80)
# svg("NOSTOC.svg",   width = 2795/80,  height = 2795/80)  # 42 Mb vectorized

par(mar = rep(0, 4))

plotIdiograms(dfChrSize = myProkaryotedf,   # chr. data d.f.
  dfMarkPos = marksDfChrCols,    # mark pos d.f.
  dfMarkColor = markStyleNostoc, # mark style d.f. style

  squareness = 21,            # corners not rounded
  n = 150,                    # number of vertices in rounded items.
  markN = 2,
  chromatids = FALSE,

  chrWidth = 4,               # chr. width
  lwd.chr  = 0.1,
  chrId = "none",             # no chr. name
  legend = "inline",          # for arrows, this mimics cM and cMLeft marks
  #
  markLabelSize = 0.25,       # font size of labels
  pattern = mypattern,        # remove pattern from mark names
  #
  ylimBotMod = 5,             # modify plot size
  ylimTopMod = 5,
  xlimLeftMod = 5,
  xlimRightMod = 5,
  #
  # # circular plot params.
  circularPlot = TRUE,      # circular
  shrinkFactor = 1,         # use 100% of circle
  labelSpacing = 1,         # label spacing from chr.
  rotation = rotaVal,       # begin chr. in top
  labelOutwards = TRUE      # label projected based on mark angle
  #
  , OTUjustif = 0.5          # OTU name centered
  , OTUplacing = "simple"    # location of OTU name, see OTUcentered
  , radius = 8               # radius of circle
  , OTUTextSize = 3          # font size of OTU name
  , cMBeginCenter = TRUE     # label of arrows (inline) start in the middle
)
dev.off()

10 Plotting alongside phylogeny


Jupyter interactive version:

Open in ColabOpen in Colab   Github   Raw


This guide shows the files to plot idiograms alongside a phylogeny

10.1 Load package

visit gitlab for installation instructions https://gitlab.com/ferroao/idiogramFISH

#load package
library(idiogramFISH) 

10.2 ggtree of iqtree and monocentrics

idiogramFISH comes with two trees and data.frames with chr. and marks’ data for the correspondent OTUs, first we will plot a tree produced with iqtree (Nguyen et al., 2015)

Load the iqtree:

We will use phytools for that (Revell, 2012)

require(ggplot2)
require(phytools)
require(ggpubr)
require(grid)   # pushViewport
require(ggtree)
# list.files(system.file('extdata', package = 'my_package') )

# find path of iqtree file
iqtreeFile    <- system.file("extdata", "eightSpIqtree.treefile", package = "idiogramFISH")

# load file as phylo object
iqtreephylo   <- read.newick(iqtreeFile) # phytools

# transform tree
iqtreephyloUM <- force.ultrametric(iqtreephylo, method = "extend") # phytools

Make a ggtree (Yu et al., 2018)

ggtreeOf8 <- ggtree(iqtreephyloUM) + geom_tiplab(size = 6)

Modify optionally graphical parameters with ggplot and ggpubr: (Wickham, 2016; Kassambara, 2019)

gbuil2      <-  ggplot_build(ggtreeOf8)       # get ggplot_built
gtgbuild    <-  ggplot_gtable(gbuil2)         # get gtable from ggplot_built
gtgbuild$layout$clip[gtgbuild$layout$name == "panel"] <- "off"                # modify gtable
ggtreeOf8b   <- as_ggplot(gtgbuild)            # back to ggplot
gtgbuildgg2 <- ggtreeOf8b +  theme(plot.margin = unit(c(1, 9.5, 3, 1.5), "cm")) # top right bottom left - modify margins

Order OTUs in data.frame of chr. data

Apply order of phylogeny to the data.frame

# Let's get the order of species in tree
ggtreeOf8TIPS <- ggtreeOf8$data[which(ggtreeOf8$data$isTip), ]
desiredOrder  <- rev(ggtreeOf8TIPS[order(ggtreeOf8TIPS$y), ]$label)

# make a vector without missing OTUs
desiredFiltered <- intersect(desiredOrder, allChrSizeSample$OTU)

# establish desired order
allChrSizeSample$OTU <- factor(allChrSizeSample$OTU, levels = desiredFiltered)

# order
allChrSizeSample     <- allChrSizeSample[order(allChrSizeSample$OTU), ]


Now we have to establish where are the OTUs in the tree, that don’t have chr. data

# Establish position of OTUs before missing data OTUs
matchres <- match(desiredOrder, desiredFiltered)
matchres[is.na(matchres)] <- "R"
reps     <- rle(matchres)
posOTUsBeforeMissing      <- as.numeric(matchres[which(matchres == "R") - 1][which(matchres[which(matchres == "R") - 1] != "R")])

# This are the OTUs that come before missing chr. data OTUs
BeforeMissing             <- desiredFiltered[posOTUsBeforeMissing]

# This is the amount of missing OTUs, spaces to add (ghost karyotypes)
valuesOfMissRepsBefore    <- reps$lengths[which(reps$values == "R")]

Plotting

Now we are ready to plot adding those arguments for addMissingOTUAfter and missOTUspacings

# plot to png file
png(file = "firstplot.png", width = 962, height = 962)

par(omi = rep(0, 4),
  mar = c(0, 1, 2, 1),
  mfrow = c(1, 2))   # one row two columns

par(fig = c(0, .3, 0, 1)) # location of left ghost plot

plot.new()           # ghost plot to the left
par(fig = c(.3, 1, 0, 1)) # location of right plot

plotIdiograms(dfChrSize = allChrSizeSample,    # data.frame of Chr. Sizes
  dfMarkPos = allMarksSample,      # d.f. of Marks (inc. cen. marks)
  dfMarkColor =  mydfMaColor,      # d.f. of mark characteristics

  squareness = 4,                  # squareness of vertices
  lwd.chr = .5,                    # width of lines
  orderChr = "name",               # order chr. by name
  centromereSize = 1.3,            # apparent cen. size
  chrWidth = .75,                  # width of chr.
  chrSpacing = .25,                # horizontal spacing of chr.
  indexIdTextSize = .4,            # font size of indices and chr. names

  karHeight = 4.8,                 # karyotype vertical relative size without spacing
  karHeiSpace = 6.5,               # karyotype vertical relative size with spacing

  nameChrIndexPos = 4,             # move the name of chr. indexes to left
  morpho = "both",                 # add chr. morphology
  chrIndex = "both",               # add chr. indices
  karIndex = TRUE,                 # add karyotype indices
  yTitle = "",                     # remove units title of ruler

  markLabelSpacer = 0              # spaces from rightmost chr. to legend

  , ylimTopMod = -.1                # modify ylim top margin
  , ylimBotMod = 2.6                # modify ylim bottom margin

  , rulerPos = -0.5                 # position of rulers
  , rulerNumberSize = .35           # font size of ruler number
  , rulerNumberPos = .4             # position of ruler numbers
  , ruler.tck = -.004               # tick size and orient.

  , addMissingOTUAfter = BeforeMissing          # OTUs after which there are ghost karyotypes - empty spaces
  , missOTUspacings    = valuesOfMissRepsBefore # number of ghost karyotypes
)

# plot to the left the ggtree
pushViewport(viewport(layout = grid.layout(1, 2)))
pushViewport(viewport(layout.pos.col = 1, layout.pos.row = 1))
print(gtgbuildgg2, newpage = FALSE)

# close png
dev.off()

10.3 plot of revBayes tree and holocentrics

Now we are going to plot a tree from revBayes (Höhna et al., 2017)

First, load the revBayes tree:

require(ggplot2)
require(phytools)
require(ggpubr)
require(grid)   # pushViewport
require(ggtree)
require(treeio)

# find path of iqtree file
revBayesFile    <- system.file("extdata", "revBayesTutorial.tree", package = "idiogramFISH")

# load file as phylo object
revBayesPhylo   <- read.beast(revBayesFile) # ggtree or treeio

# transform tree
revBayesPhyloUM <- force.ultrametric(revBayesPhylo@phylo, method = "extend") # phytools

Order OTUs in data.frame of chr. data

# Get order of OTUs in tree
is_tip           <- revBayesPhyloUM$edge[, 2] <= length(revBayesPhyloUM$tip.label)
ordered_tips     <- revBayesPhyloUM$edge[is_tip, 2]
desiredorderRevB <- rev(revBayesPhyloUM$tip.label[ordered_tips])

# Ceate some holocentrics' data

allChrSizeSampleHolo <- allChrSizeSample
allChrSizeSampleHolo <- allChrSizeSampleHolo[, c("OTU", "chrName", "longArmSize")]
colnames(allChrSizeSampleHolo)[which(names(allChrSizeSampleHolo) == "longArmSize")] <- "chrSize"

allMarksSampleHolo   <- allMarksSample
allMarksSampleHolo   <- allMarksSampleHolo[which(allMarksSampleHolo$chrRegion != "cen"), ]
allMarksSampleHolo   <- allMarksSampleHolo[c("OTU", "chrName", "markName", "markDistCen", "markSize")]
colnames(allMarksSampleHolo)[which(names(allMarksSampleHolo) == "markDistCen")] <- "markPos"
allMarksSampleHolo[which(allMarksSampleHolo$markName == "5S"), ]$markSize <- .5

# Apply order of phylogeny to data.frame

# make a vector without missing OTUs
desiredFiltered <- intersect(desiredorderRevB, allChrSizeSampleHolo$OTU)

# establish desired order
allChrSizeSampleHolo$OTU <- factor(allChrSizeSampleHolo$OTU, levels = desiredFiltered)

# order
allChrSizeSampleHolo <- allChrSizeSampleHolo[order(allChrSizeSampleHolo$OTU), ]


Now we have to establish where are the OTUs in the tree, that don’t have chr. data

# Establish position of OTUs before missing data OTUs
matchres <- match(desiredorderRevB, desiredFiltered)
matchres[is.na(matchres)]   <- "R"
reps     <- rle(matchres)
posOTUsBeforeMissing        <- as.numeric(matchres[which(matchres == "R") - 1][which(matchres[which(matchres == "R") - 1] != "R")])

# This are the OTUs that come before missing chr. data OTUs
BeforeMissingPlot2          <- desiredFiltered[posOTUsBeforeMissing]

# This is the amount of missing OTUs, spaces to add (ghost karyotypes)
valuesOfMissRepsBeforePlot2 <- reps$lengths[which(reps$values == "R")]

Plotting

Now we are ready to plot adding those arguments for addMissingOTUAfter and missOTUspacings

# plot to png file
png(file = paste0("secondplot.png"), width = 962, height = 700)

{
  par(omi = rep(0, 4), mar = c(0, 0, 0, 0), mfrow = c(1, 2))
  par(fig = c(0, .27, 0, 1))
  par(mar = c(2, 0, 2, 0)) # b l t r

  plot(revBayesPhyloUM)
  par(fig = c(0.27, 1, 0, 1), new = TRUE)
  par(mar = c(0, 0, 0, 0)) # b l t r

  plotIdiograms(allChrSizeSampleHolo,   # chr. size data.frame
    dfMarkPos = allMarksSampleHolo,     # data.frame of marks' positions
    dfMarkColor =  mydfMaColor,         # d.f. of mark characteristics

    squareness = 4,                     # vertices squareness
    karHeight = 2.8,                    # karyotype height
    karHeiSpace = 4.5,                  # vertical size of kar. including spacing
    yTitle = "",

    karIndex = TRUE,                    # add karyotype index
    indexIdTextSize = .4                # font size of indices and chr. names

    , addMissingOTUAfter = BeforeMissingPlot2           # add ghost OTUs after these names
    , missOTUspacings    = valuesOfMissRepsBeforePlot2  # how many ghosts, respectively
    , lwd.chr = .5                       # line width

    , markLabelSpacer = 0                # dist. of legend to rightmost chr.
    , legendWidth = 2.3                  # width of square or dots of legend

    , rulerPos = -0.5                    # position of ruler
    , rulerNumberSize = .35              # font size of number of ruler
    , rulerNumberPos = .4                # position of ruler number
    , ruler.tck = -.004                  # tick of ruler size and orient.

    , ylimTopMod = -4                    # modify ylim of top
    , ylimBotMod = -4                    # modify ylim of bottom
    , xlimRightMod = 3                   # modify xlim right argument
    , xModifier = 100                    # separ. among chromatids
  )
}

# close png
dev.off()

10.4 plot of revBayes tree and holocentrics and monocentrics

Create data.frames with both types of karyotypes (Wickham, 2011)

require(plyr)
# Select this OTU from the monocen.
monosel <- c("Species_F", "Species_C", "Species_A")
# chr.
allChrSizeSampleSel  <- allChrSizeSample [which(allChrSizeSample$OTU  %in% monosel), ]
# marks
allMarksSampleSel    <- allMarksSample   [which(allMarksSample$OTU    %in% monosel), ]

# Select the others from the holocen.
holosel    <- setdiff(unique(allChrSizeSampleHolo$OTU), monosel)
# chr.
allChrSizeSampleHoloSel <- allChrSizeSampleHolo[which(allChrSizeSampleHolo$OTU %in% holosel), ]
# marks
allMarksSampleHoloSel   <- allMarksSampleHolo  [which(allMarksSampleHolo$OTU   %in% holosel), ]

# merge chr d.fs
mixChrSize <- plyr::rbind.fill(allChrSizeSampleSel, allChrSizeSampleHoloSel)

# merge marks' d.fs
mixMarks   <- plyr::rbind.fill(allMarksSampleSel, allMarksSampleHoloSel)


Order data.frame and determine missing karyotypes

# make a vector without missing OTUs
desiredFiltered <- intersect(desiredorderRevB, mixChrSize$OTU)

# establish desired order
mixChrSize$OTU <- factor(mixChrSize$OTU, levels = desiredFiltered)

# order data.frame
mixChrSize <- mixChrSize[order(mixChrSize$OTU), ]

# Establish position of OTUs before missing data OTUs
matchres <- match(desiredorderRevB, desiredFiltered)
matchres[is.na(matchres)]   <- "R"
reps     <- rle(matchres)
posOTUsBeforeMissing        <- as.numeric(matchres[which(matchres == "R") - 1][which(matchres[which(matchres == "R") - 1] != "R")])

# This are the OTUs that come before missing chr. data OTUs
BeforeMissingPlot2          <- desiredFiltered[posOTUsBeforeMissing]

# This is the amount of missing OTUs, spaces to add (ghost karyotypes)
valuesOfMissRepsBeforePlot2 <- reps$lengths[which(reps$values == "R")]

Plotting

Now we are ready to plot adding those arguments for addMissingOTUAfter and missOTUspacings

# plot to png file
png(file = paste0("thirdplot.png"), width = 1100, height = 1000)
{
  par(omi = rep(0, 4), mar = c(0, 0, 0, 0), mfrow = c(1, 2))
  par(fig = c(0, .25, 0, 1))
  par(mar = c(1, 0, 0, 0))

  plot(revBayesPhyloUM)
  par(fig = c(0.25, 1, 0, 1), new = TRUE)
  par(mar = c(0, 0, 0, 0))

  plotIdiograms(mixChrSize,             # chr. size data.frame
    dfMarkPos = mixMarks,               # data.frame of marks' positions (inc. cen. marks)
    dfMarkColor = mydfMaColor,          # d.f. of mark characteristics

    origin = "b",                       # position measured from bottom of chr.

    karHeight = 2.8,                    # vertical size of kar. including spacing
    karHeiSpace = 4.5,                  # vertical size of kar. including spacing
    squareness = 5,                     # vertices squareness
    chrSpacing = .25,                   # horizontal spacing among chr.
    yTitle = "",

    karIndex = TRUE                     # add karyotype index
    , indexIdTextSize = .4              # font size of indices and chr. names
    , distTextChr = 0.7                 # dist. among chr. and chr. name

    , addMissingOTUAfter = BeforeMissingPlot2           # add ghost OTUs after these names
    , missOTUspacings    = valuesOfMissRepsBeforePlot2  # how many ghosts, respectively
    , lwd.chr = .5                       # line width

    , markLabelSpacer = 0                # dist. of legend to rightmost chr.
    , legendWidth = 2                    # width of square or dots of legend

    , ylimTopMod = -2                    # modify ylim of top
    , ylimBotMod = -2                    # modify ylim of bottom

    , rulerPos = -0.5                    # position of ruler
    , rulerNumberSize = .35              # font size of number of ruler
    , rulerNumberPos = .4                # position of ruler number
    , ruler.tck = -.004                  # ruler tick size and orient.
    , OTUfont = 3                        # italics
    , OTUfamily = "Courier New"          # for OTU name

    , xModMonoHoloRate = 5               # factor (quotient) to shrink separation of chromatids of holocen.

  )
}
# close png
dev.off()

11 Citrus


Jupyter interactive version:

Open in ColabOpen in Colab   Github   Raw


11.1 C. maxima as da-Costa-Silva et al. (2019)

master data.frame of chr. size and marks

From this special data.frame citrusMaximaChrMark we will get two of the three canonical data.frames:

  • One for chr. sizes (parameter dfChrSize)
  • One for marks’ positions (parameter dfMarkPos)
  • One (optional) for mark style (parameter dfMarkColor)

Column chrNameUp will be used in this case for unifying the chr. names (chrName) in the 1st and 2nd data.frames.

# C. maxima 'pink'
# 4A 2C 4D 6F 2FL

{
  citrusMaximaChrMark <- read.table(text = "
chrName chrNameUp shortArmSize  longArmSize markName    chrRegion   markDistCen markSize
FL 1    67  97  24c13   p   52  10
D  2    62  75  21L13   q   35  8
D  2    62  75  CMA     q   43  32
A  3    70  103 45S     p   6   16
A  3    70  103 14A12   p   32  8
A  3    70  103 CMA     p   40  30
A  3    70  103 28A07   q   54  10
A  3    70  103 CMA     q   64  39
D  4    59  84  02C12   p   31  10
D  4    59  84  20C13   q   32  9
D  4    59  84  cma     q   48  36
F  5    52  74  5s      p   18  10
C  6    62  86  28A05   p   22  9
C  6    62  86  cma     p   40  22
C  6    62  86  cma     q   61  25
A  7    57  96  45S     p    6  18
A  7    57  96  cma     p   38  19
A  7    57  96  cma     q   62  34
F  8    41  72  01b09   q   47  8
F  9    40  72  55b01/59C23   q 24  13", header = TRUE)
}

data.frame of chr. sizes

Main columns: chrName, shortArmSize, longArmSize, OTU (optional when only one OTU), group (optional)

Column chrNameUp will be used in this case for unifying the chr. names (chrName) between data.frames.

{
  require(idiogramFISH)

  # column and row subset
  citrusMaxima <- citrusMaximaChrMark[, 1:4][!duplicated(citrusMaximaChrMark[, 1:4]), ]

  # chr. name change (unique)
  citrusMaxima$chrName <- make.uniqueIF(citrusMaxima$chrName)

  # chr. size in pixels
  chrSizes <- citrusMaxima$shortArmSize + citrusMaxima$longArmSize

  # max. size in μm.
  maxSize <- 3.6
  maxPixel <- max(chrSizes)

  # pixel to microm.
  citrusMaxima$shortArmSize <- citrusMaxima$shortArmSize / (maxPixel / maxSize)
  citrusMaxima$longArmSize <- citrusMaxima$longArmSize / (maxPixel / maxSize)

  citrusMaxima$OTU <- "C. maxima 'Pink'"

  # add groups (pairs)
  citrusMaxima$group <- 1:9
}

data.frame of marks’ positions

Main columns: chrName, markName, chrRegion (arm), markDistCen (mark distance to centr.), markSize

Column chrNameUp will be used in this case for unifying the chr. names (chrName) between data.frames.

Column OTU is mandatory because is present in first data.frame (citrusMaxima)

{
  # Select columns
  citrusMaximaMarkPos <- citrusMaximaChrMark[, c(1:2, 5:8)][!duplicated(citrusMaximaChrMark[, c(1:2, 5:8)]), ]

  # transcribe chr.names - changed above. needs common column (i.e. chrNameUp)
  citrusMaximaMarkPos$chrName <- citrusMaxima$chrName[match(citrusMaximaMarkPos$chrNameUp, citrusMaxima$chrNameUp)]

  # pixel to μm.
  citrusMaximaMarkPos$markDistCen <- citrusMaximaMarkPos$markDistCen / (maxPixel / maxSize)
  citrusMaximaMarkPos$markSize <- citrusMaximaMarkPos$markSize / (maxPixel / maxSize)

  # OTU column
  citrusMaximaMarkPos$OTU <- unique(citrusMaxima$OTU)

  # fix case
  citrusMaximaMarkPos$markName <- toupper(citrusMaximaMarkPos$markName)
}

data.frame of marks’ style

Optional data.frame. Add color and style for marks present in citrusMaximaMarkPos

{
  unique(citrusMaximaMarkPos$markName)
  # "24C13" "21L13" "CMA" "45S" "14A12"   "28A07" "02C12"   "20C13" "5S"  "28A05" "01B09" "55B01/59C23"

  # make d.f. of styles of marks
  markStyleDF   <- makedfMarkColorMycolors(
    unique(citrusMaximaMarkPos$markName),
    c("chocolate", "chocolate", "darkgoldenrod1", "chartreuse3", rep("chocolate", 4), "red", rep("chocolate", 3))
  )

}

Notes and plot

Two optional data.frames for adding notes to plot with columns OTU and note.

Parameters: leftNotes and notes

# notes
{
  # formula
  maxima <- "4A + 2C + 4D + 6F + 2FL [4A/45S, 2F/5S]"
  leftNotesdf <- data.frame(OTU = unique(citrusMaxima$OTU), note = maxima)

  # authors
  notesdf <- data.frame(OTU = unique(citrusMaxima$OTU), note = "da-Costa-Silva et al. 2019")
}

# add group column to show that each one is a pair
{
  par(mar = rep(0, 4), oma = rep(0, 4))
  plotIdiograms(dfChrSize = citrusMaxima,        # chr. size data.frame
    dfMarkPos = citrusMaximaMarkPos,  # mark position data.frame
    dfMarkColor = markStyleDF,        # mark style d.f.

    orderChr = "original",    # order of chr. as in d.f.
    chrIdPatternRem = "_.*",  # regex pattern to remove from chr. names
    classChrName = "Type",    # chr. names title
    chrWidth = 0.3,           # chr. width
    chrSpacing = 0.40,        # separ. among chr.
    groupSepar = 1            # factor to multiply chr. spacing among groups
    , chromatids = FALSE      # don't use chromatids
    , chrColor = "white"    # chr. color
    , classGroupName = "Pair" # groups title
    , chrBorderColor = "black" # border color
    , lwd.chr = 0.5           # border width

    , legend = "inline"        # label location
    , bannedMarkName = c("CMA", "45S", "5S") # don't show this (inline)
    , bMarkNameAside = TRUE    # show banned marks "aside"
    , legendHeight = 1.7       # height of labels (aside)
    , colorBorderMark = "black" # color of border of marks

    , markNewLine = "/"        # split mark name to new line

    , ruler = FALSE            # don't use ruler
    , threshold = 40           # fix scale, when too much shrinking

    , distTextChr = .7         # distance text to chr.
    , chrIndex = ""            # don't use chr. indices
    , morpho = ""              # don't use morphology
    , karIndex = FALSE         # don't use kar. indices

    , OTUfont = 3              # OTU name in italics

    , leftNotesTextSize = 1.3  # font size of notes
    , notesTextSize = 1.3      # font size of notes

    , leftNotes = leftNotesdf  # data.frame with left notes
    , leftNotesPosX = 0        # horizontal pos. of formula
    , leftNotesPosY = 0.5,
    notes = notesdf          # right notes - authors

    , ylimBotMod = 1         # modify ylim bottom argument
    , ylimTopMod = 0         # modify ylim top argument
    , xlimLeftMod = 2        # modify left xlim
    , xlimRightMod = 3       # modify right xlim
  )
}

11.2 C. reticulata as da-Costa-Silva et al. (2015)

Chr. size data.frame


#
#   chr. size - arms in pixels
#

{
  citrusReticulata <- read.table(text = "
chrName shortArmSize longArmSize totalMicro  Mbp   group
f       67            91          2.65       50.96 1
d       61            77          2.32       44.60 2
c       59            78          2.18       41.81 3
d       61            83          2.49       47.75 4
d       34            63          1.87       35.90 5
d       34            63          1.87       35.90 5
d       50            66          1.93       37    6
d       50            83          2.28       43.72 7
f       42            77          2.02       38.78 8
f       28            67          1.70       32.57 9", header = TRUE)

  citrusReticulata$pixeltotal <- citrusReticulata$shortArmSize + citrusReticulata$longArmSize

  # pixel to micrometers
  citrusReticulata$shortArmSize <- citrusReticulata$shortArmSize / (citrusReticulata$pixeltotal / citrusReticulata$totalMicro)
  citrusReticulata$longArmSize <- citrusReticulata$longArmSize / (citrusReticulata$pixeltotal / citrusReticulata$totalMicro)

  # change chr. names avoiding duplicates
  citrusReticulata$chrName <- toupper(citrusReticulata$chrName)
  citrusReticulata$chrName <- make.uniqueIF(citrusReticulata$chrName)

  # add OTU
  citrusReticulata$OTU <- "C. reticulata 'Cravo'"

  # replicate name for plotting it over chrs.
  citrusReticulata$chrNameUp <- citrusReticulata$chrName
}

Marks

citrusReticulataMarkPosDF <-  read.table(text = "
chrName chrRegion markName markDistCen markSize
     F_1      p    24C13   0.87  0.12
       C      p      CMA   0.64  0.30
       C      q      CMA   0.84  0.40
       C      p     14A12  0.48  0.11
       C      q    28A07   0.77  0.14
       C      p      45S   0.00  0.10
     D_1      q      CMA   0.54  0.75
     D_1      p    21L13   0.67  0.14
     D_2      q      CMA   0.88  0.55
     D_2      p    02C12   0.5   0.14
     D_2      q    20C13   0.42  0.14
     D_3      p      CMA   0.35  0.30
     D_3      p     c45S   0.35  0.35
     D_3      p      CMA   0.8   0.15
     D_3      p     c45S   0.8   0.15
     D_4      p      CMA   0.35  0.30
     D_4      p      45S   0.35  0.30
     D_5      p    28A05   0.66  0.14
     D_5      q      CMA   0.50  0.60
     D_6      q      CMA   0.72  0.70
     F_2      q    01B09   0.8   0.14
     F_3      q    55B01   0.3   0.18
     F_3      q    59C23   0.3   0.18", header = TRUE, stringsAsFactors = FALSE)

# marks' style data.frame
unique(citrusReticulataMarkPosDF$markName)
#  [1] "24C13" "CMA"   "14A12" "28A07" "45S"   "21L13" "02C12" "20C13" "c45S" 
# [10] "28A05" "01B09" "55B01" "59C23"

markStyleDF   <- makedfMarkColorMycolors(
  unique(citrusReticulataMarkPosDF$markName),
  c("chocolate", "darkgoldenrod1", "chocolate", "chocolate", "chartreuse3", rep("chocolate", 3), "chartreuse3", rep("chocolate", 4))
)

# square mark with label to the left (squareLeft style)
markStyleDF[which(markStyleDF$markName == "59C23"), ]$style <- "squareLeft"

# add OTU!
citrusReticulataMarkPosDF$OTU <- unique(citrusReticulata$OTU)

Plotting


# notes to the left
reticulata <- "2C + 10D + 6F [2C/45S, 2D/45S]"

leftNotesdf <- data.frame(OTU = unique(citrusReticulata$OTU), note = reticulata)

# authors in notes (right side)
notesdf <- data.frame(OTU = unique(citrusReticulata$OTU), note = "da-Costa-Silva et al. (2015)")

par(mar = rep(0, 4), oma = rep(0, 4))

{
  require(idiogramFISH)
  plotIdiograms(dfChrSize = citrusReticulata,         # chr. size data.frame
    dfMarkPos = citrusReticulataMarkPosDF, # mark position data.frame (inc. cen.)
    dfMarkColor = markStyleDF, # mark style d.f.

    orderChr = "original",    # order of chr. as in d.f.
    chrIdPatternRem = "_.*",  # pattern to remove from chr. names

    chrColor = "white"       # color of chr.
    , chrBorderColor = "black" # borders

    , chrIndex = "AR"        # add index r
    , morpho = ""            # don't add morphology cat.
    , karIndex = FALSE       # don't add kar. indeex
    , chrNameUp = TRUE       # add. info. of col. chrNameUp over kar.

    , centromereSize = 0     # size of cen.
    , colorBorderMark = "black" # color of border of marks
    , lwd.chr = 1            # border width

    , OTUfont = 3            # OTU name in italics

    , leftNotes = leftNotesdf # data.frame with notes
    , leftNotesTextSize = 1  # font size of notes
    , notesTextSize = 1      # font size of notes

    , leftNotesPosX = 0      # horizontal pos. of formula- left notes
    , leftNotesPosY = 1.9    # y pos. of left notes

    , notes = notesdf        # authors in notes (right)
    , notesPosX = 1          # move right notes to right

    , rulerInterval = .5     # ruler label int.
    , ruler.tck = -.01       # ruler ticks
    , rulerPos = -0.5        # ruler pos.
    , xPosRulerTitle = 7     # move title (units) of ruler, beginning in 1st chr.

    , ylimBotMod = 2         # modify ylim bottom argument
    , ylimTopMod = 1         # modify ylim top argument
    , xlimLeftMod = 1        # modify left xlim
    , xlimRightMod = 2       # modify right xlim

    , chromatids = FALSE     # do not plot chromatids
    , squareness = 2         # corners rounded
    , useMinorTicks = TRUE   # ruler minor ticks
    , miniTickFactor = 5     # number of small ticks per big ticks
    , distTextChr = .7       # distance indices to chr.

    , chrId = ""             # don't add chr. names (below)
    , chrSize = TRUE         # add chr. size
    , chrSizeMbp = TRUE      # add info of col. Mbp
    , nsmall = 2             # significative digits for indices

    , markPer = "CMA"        # calculate % of chr. for this mark
    , showMarkPos = TRUE     # show mark. position as fraction, under kar.
    , bToRemove = c("CMA", "45S", "c45S")   # do not use these in showMarkPos

    , legend = "inline"         # labels inline
    , legendHeight = 1.5        # legend height (right)
    , bannedMarkName = "CMA"    # do not add label of this mark
    , bMarkNameAside = TRUE     # add banned mark aside
    , forbiddenMark = "c45S"    # do not add this mark label

    , groupSepar = 1.8       # separation among groups, see col. group (x chrSpacing)
    , chrSpacing = .20       # separ. among chr.
    , chrWidth = .20         # chr. width
    , nameChrIndexPos = 4    # move name of indices to the left
  )
}

Download Citrus scripts from: https://ferroao.gitlab.io/idiogramfishhelppages/citrushelp.R{target = “_blank”}

11.3 Exploring Citrus functions

Details of functions can be found with:

?citrusSize 
?citrusMarkPos 
?markOverCMA

Or in: https://ferroao.gitlab.io/idiogramFISH/reference/citrusSize.html{target = “_blank”}

Published by Carvalho et al. (2005)

C. jambhiri/ C. volkameriana

1B + 11D + 4F + 2FL0

Create data.frame of chr. size

{
  library(idiogramFISH)

  citrusSizeDF <- citrusSize(B = 1, D = 11, F = 4, FL0 = 2,
    OTU = "C. jambhiri")

  # add simple secondary names
  citrusSizeDF$chrNameUp <- seq_len(nrow(citrusSizeDF))

  head(citrusSizeDF, 3)
  tail(citrusSizeDF, 3)

  # Editing data.frame:
  # citrusSizeDF <- edit(citrusSizeDF)

  # Initial plot, only sizes:
  par(mar = rep(0, 4), oma = rep(0, 4))
  plotIdiograms(dfChrSize = citrusSizeDF,      # chr. size data.frame
    orderChr = "original",        # order of chr.
    ruler = FALSE,
    ylimBotMod = 2,               # modify bottom margin
    ylimTopMod = 1,

    chrNameUp = TRUE,             # use col. chrNameUp
    classChrName = "Type",        # change default title of inferior name
    classChrNameUp = "Chr."       # change default title of upper name
  )
}

Use the group column to define pairs

citrusSizeDF$chrName
 [1] "B"     "D_1"   "D_2"   "D_3"   "D_4"   "D_5"   "D_6"   "D_7"   "D_8"  
[10] "D_9"   "D_10"  "D_11"  "F_1"   "F_2"   "F_3"   "F_4"   "FL0_1" "FL0_2"

# " "B" "D_1" "D_2" "D_3" "D_4" "D_5" "D_6" "D_7" "D_8"   "D_9"  "D_10"  "D_11"  "F_1"   "F_2"   "F_3"   "F_4"   "FL0_1" "FL0_2"
#   -------   ---------   ---------   ---------   -----------    ------------    -----------    ------------     -------------
# "     1          2           3           4            5              6              7               8                9

citrusSizeDF$group <- unlist(lapply(1:9, function(x) rep(x, 2)))
citrusSizeDF$group
 [1] 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9

# make secondary names
citrusSizeDF$chrNameUp <- unlist(lapply(1:9, function(x) rep(x, 2)))
citrusSizeDF$chrNameUp <- make.uniqueIF(citrusSizeDF$chrNameUp, sep = "", letter = TRUE)

data.frame of marks’ position


# CMA bands
citrusMarkPosDF <- citrusMarkPos(citrusSizeDF)
head(citrusMarkPosDF, 3)
#   chrName chrRegion markName markDistCen markSize         OTU
# 1       B         p      CMA        0.00     0.35 C. jambhiri
# 2       B         q      CMA        1.35     0.35 C. jambhiri
# 3     D_1         q      CMA        1.35     0.35 C. jambhiri
tail(citrusMarkPosDF, 3)
#    chrName chrRegion markName markDistCen markSize         OTU
# 11     D_7         q      CMA        1.35     0.35 C. jambhiri
# 12     D_8         q      CMA        1.35     0.35 C. jambhiri
# 13     D_9         q      CMA        1.35     0.35 C. jambhiri

# marks with overlap with CMA

# add mark of 45S rDNA in B, short arm (p)
citrusMarkPosDF45S <- markOverCMA(citrusMarkPosDF, # d.f. of CMA bands
  chrType = "B",       # chr. of new mark
  chrRegion = "p",     # arm of new mark
  markName = "45S")    # name of mark

# add 45S in D (D_1) long arm
citrusMarkPosDF45S <- markOverCMA(citrusMarkPosDF45S, # d.f. including CMA bands
  chrName = "D_1",
  chrRegion = "q",
  markName = "45S")

# creating additional data.frames of marks (non-CMA overlap)

citrusMarkPosDF45S_D11 <- data.frame(chrName = "D_11", # cr.
  chrRegion = "q",  # arm
  markName = "45S",
  markDistCen = 1,  # dist. to centrom.
  markSize = 0.2,   # mark size
  OTU = "C. jambhiri")

citrusMarkPosDF45S_F4  <- data.frame(chrName = "F_4",
  chrRegion = "q",
  markName = "45S",
  markDistCen = 1,
  markSize = 0.2,
  OTU = "C. jambhiri")

# fuse data.frames
citrusMarkPosDF45S <- dplyr::bind_rows(citrusMarkPosDF45S,     # CMA marks and overlapped
  citrusMarkPosDF45S_D11, # 45S in D (no overlap)
  citrusMarkPosDF45S_F4)  # 45S in F (no overlap)

data.frame of mark style

# current marks
unique(citrusMarkPosDF45S$markName)
## [1] "CMA" "45S"

markStyleDF   <- makedfMarkColorMycolors(
  unique(citrusMarkPosDF45S$markName), c("darkgoldenrod1", "chartreuse3"))

# modify styles
markStyleDF$style <- c("square", "dots")

Add karyotype formulas

notesdf<- data.frame(OTU = unique(citrusSizeDF$OTU), note = "1B + 11D + 4F + 2FL0") # spacing matters

Plot

par(mar = rep(0, 4), oma = rep(0, 4))
library(idiogramFISH)
plotIdiograms(dfChrSize = citrusSizeDF,      # chr. size data.frame
  dfMarkPos = citrusMarkPosDF45S, # mark position data.frame (inc. cen.)
  dfMarkColor = markStyleDF,      # mark style d.f.

  orderChr = "original",        # preserve order of chr. of d.f.

  # chrId = "",                 # remove name of chr.
  chrIdPatternRem = "_.*",      # regex pattern for removal of names of chr.
  chrSpacing = 0.2,             # separ. among chr.
  chrColor = "dodgerblue",

  chrNameUp = TRUE,             # use col. chrNameUp
  classChrName = "Type",        # change default title of inferior name
  classChrNameUp = "Chr."       # change default title of upper name

  , legendWidth = .8             # legend item width
  , legendHeight = 3             # legend item height
  , markLabelSpacer = 2          # legend spacer
  , ruler = FALSE                # no ruler
  , chrIndex = ""                # no chr. index
  , morpho = ""                  # no morpho.
  , karIndex = FALSE             # no kar. ind.

  , leftNotes = notesdf          # data.frame with notes
  , leftNotesTextSize = 1.3      # font size of notes
  , leftNotesPosX = 10.2         # pos. formula x axis
  , leftNotesPosY = 0            # pos. formula y axis

  , ylimBotMod = 1               # modify ylim bottom argument
  , xlimRightMod = 4             # modify right xlim
)

11.4 Representing only one chromosome per pair

As in the article (Carvalho et al., 2005)

C. jambhiri/ C. volkameriana

1B + 11D + 4F + 2FL0

{
  # data.frame of  chr. sizes
  citrusSizeDF_2 <- citrusSize(B = 1, D = 8, F = 3, FL0 = 1, # MODIFIED, SEE ABOVE
    OTU = "C. jambhiri_2")
  head(citrusSizeDF_2)

  # data.frame of CMA band pos.
  citrusMarkPosDF_2 <- citrusMarkPos(citrusSizeDF_2)
  head(citrusMarkPosDF_2)

  # marks with overlap with CMA

  # 45S in B, short arm
  citrusMarkPosDF45S_2 <- markOverCMA(citrusMarkPosDF_2,
    chrType = "B",
    chrRegion = "p",
    markName = "45S")

  # 45S in D (D_1), long arm
  citrusMarkPosDF45S_2 <- markOverCMA(citrusMarkPosDF45S_2,
    chrName = "D_1",
    chrRegion = "q",
    markName = "45S")

  # add mark from scratch (no overlap with CMA)

  citrusMarkPosDF45S_D8  <- data.frame(chrName = "D_8", # name of chr.
    chrRegion = "q", # arm
    markName = "45S", #
    markDistCen = 1, # dist. to centrom.
    markSize = 0.2,  # mark size
    OTU = "C. jambhiri_2")

  citrusMarkPosDF45S_F3  <- data.frame(chrName = "F_3",
    chrRegion = "q",
    markName = "45S",
    markDistCen = 1,
    markSize = 0.2,
    OTU = "C. jambhiri_2")
  # fuse data.frames
  citrusMarkPosDF45S_2 <- dplyr::bind_rows(citrusMarkPosDF45S_2,
    citrusMarkPosDF45S_D8,
    citrusMarkPosDF45S_F3
  )

  # current marks
  unique(citrusMarkPosDF45S_2$markName)

  # data.frame of mark style
  markStyleDF   <- makedfMarkColorMycolors(
    unique(citrusMarkPosDF45S_2$markName), c("darkgoldenrod1", "chartreuse3"))

  # modify styles
  markStyleDF$style <- c("square", "dots")

  # organize pairs, group

  citrusSizeDF_2$chrName
  # "B"   "D_1"  "D_2" "D_3" "D_4" "D_5" "D_6" "D_7" "D_8" "F_1" "F_2" "F_3" "FL0"
  #  ________    ____   ___   ________   ____   _________   ____   ________   ___
  #     1          2     3       4         5        6         7        8       9

  citrusSizeDF_2$group <- c(1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9)

  # add names over chr.
  citrusSizeDF_2$chrNameUp <- citrusSizeDF_2$group
  citrusSizeDF_2$chrNameUp <- make.uniqueIF(citrusSizeDF_2$chrNameUp, sep = "", letter = TRUE)

  # formula
  notesdf <- data.frame(OTU = unique(citrusSizeDF_2$OTU), note = "1B + 11D + 4F + 2FL0") # keep spacing
}

par(mar = c(0, 0, 0, 0), oma = rep(0, 4))
library(idiogramFISH)
plotIdiograms(dfChrSize = citrusSizeDF_2,      # d.f. of chr. size
  dfMarkPos = citrusMarkPosDF45S_2, # d.f. of mark pos
  dfMarkColor = markStyleDF,        # d.f. of mark style
  orderChr = "original",          # chr. order as in d.f.
  chrIdPatternRem = "_.*",        # modif name of chr. removing this pattern
  chrSpacing = .20,               # separ. among chr.
  chrColor = "dodgerblue",
  legendWidth = .8            # legend item width
  , legendHeight = 2.5        # legend item height
  , markLabelSpacer = 2       # legend spacer
  , ruler = FALSE,
  chrIndex = "",
  morpho = "",
  karIndex = FALSE,
  chrNameUp = TRUE           # use col. chrNameUp
  , classChrName = "Type"    # change default title of inferior name
  , classChrNameUp = "Chr."  # change default title of upper name
  , classGroupName = "Pair"  # name for groups

  , leftNotes = notesdf        # data.frame with notes
  , leftNotesTextSize = 1.3    # font size of notes
  , leftNotesPosX = 10.2       # formula horiz. pos.
  , leftNotesPosY = 0,
  ylimBotMod = 1               # modify ylim bottom argument
  , ylimTopMod = 0             # modify ylim top argument
  , xlimLeftMod = 2            # modify left xlim
  , xlimRightMod = 3           # modify right xlim
)

11.5 Several karyotypes per plot

Column OTU is mandatory for several OTU.

# data.frames of size - merge
bothSize    <- dplyr::bind_rows(citrusSizeDF, citrusSizeDF_2)

# data.frames of band pos. merge
bothMarkPos <- dplyr::bind_rows(citrusMarkPosDF45S, citrusMarkPosDF45S_2)

# formulas

notesdf <- data.frame(OTU = unique(bothSize$OTU), note = "1B + 11D + 4F + 2FL0")

par(mar = rep(0, 4), oma = rep(0, 4))

plotIdiograms(dfChrSize = bothSize,    # chr. size data.frame
  dfMarkPos = bothMarkPos,   # mark position data.frame (inc. cen.)
  dfMarkColor = markStyleDF, # mark style d.f.

  orderChr = "original",   # order of chr. as in d.f.
  chrIdPatternRem = "_.*", # pattern to remove from chr. names
  karHeight = 2,           # karyotype height
  karHeiSpace = 5,         # height + separ. among karyot.

  chrSpacing = .20,         # separ. among chr.
  chrColor = "dodgerblue",
  distTextChr = .9          # distance text to chr.

  , legendWidth = .8       # legend item width
  , legendHeight = 3       # legend item height
  , markLabelSpacer = 2    # legend spacer
  , ruler = FALSE,
  chrIndex = "",
  morpho = "",
  karIndex = FALSE
  # ,colorBorderMark = "black"# color of border of marks
  , lwd.chr = 1            # border width

  , chrNameUp = TRUE       # use col. chrNameUp
  , classChrName = "Type"  # change default title of inferior name
  , classChrNameUp = "Chr." # change default title of upper name
  , groupName = FALSE      # don't show group names

  , OTUfont = 3            # OTU name in italics

  , leftNotes = notesdf    # data.frame with notes
  , leftNotesTextSize = 1.3 # font size of notes
  , leftNotesPosX = 10.2   # horizontal pos. of formula
  , leftNotesPosY = 0,
  ylimBotMod = 1           # modify ylim bottom argument
  , ylimTopMod = 0         # modify ylim top argument
  , xlimLeftMod = 2        # modify left xlim
  , xlimRightMod = 3       # modify right xlim
)

11.6 C. leiocarpa as Yi et al. (2018)


#
# create data.frame of chr.
#

cleiocarpaChr <- citrusSize(A = 1, C = 1, D = 10, F = 6, # Using Guerra nom.
  OTU = "C. leiocarpa",
  shortArm = 1.7
)

#
# add groups
#

cleiocarpaChr$group <- gsub("_.*", "", cleiocarpaChr$chrName)

#
# marks data.frame
#

# CMA
cleiocarpaMarks <- citrusMarkPos(cleiocarpaChr)

# marks with overlap with CMA

# add mark of 45S rDNA in A, short arm (p)
cleiocarpaMarks <- markOverCMA(cleiocarpaMarks, # d.f. of CMA bands
  chrType = "A",       # chr. of new mark
  chrRegion = "p",     # arm of new mark
  markName = "45S",    # name of mark
  shrinkMark = TRUE
)
# add 45S in Ds
cleiocarpaMarks <-  markOverCMA(cleiocarpaMarks, # d.f. including CMA bands
  chrName = paste0("D_", 1:4),
  chrRegion = "q",
  markName = "45S",
  shrinkMark = TRUE
)

# creating additional data.frames of marks (non-CMA overlap)

cleiocarpaMarks_D3 <- data.frame(chrName = c("D_3", "D_4"), # cr.
  chrRegion = "q",   # arm
  markName = "5S",
  markDistCen = 1.1, # dist. to centrom.
  markSize = 0.2,    # mark size
  OTU = "C. leiocarpa")

#
# merge marks d.fs
#

cleiocarpaMarks <- dplyr::bind_rows(cleiocarpaMarks,    # CMA marks and overlapped 45S
  cleiocarpaMarks_D3, # 5S in D (no overlap)
)
#
# mark style data.frame
#

# current marks
unique(cleiocarpaMarks$markName)
# [1] "CMA" "45S" "5S"

markStyleDF   <- makedfMarkColorMycolors(
  unique(cleiocarpaMarks$markName), c("darkgoldenrod1", "chartreuse3", "red")
)

# modify styles
markStyleDF$style <- c("square", "dots", "dots")

#
# swap chromosome arms of Ds (CMA marks originally in long arm)
#

dflist <- swapChrRegionDfSizeAndMarks(cleiocarpaChr,
  cleiocarpaMarks,
  paste0("D_", 1:10)
)
cleiocarpaChr   <- dflist$dfChrSize
cleiocarpaMarks <- dflist$dfMarkPos

#
# Left notes Up data.frame
#

notesdf <- data.frame(OTU = unique(cleiocarpaChr$OTU),
  note = "italic('Citrus leiocarpa'),' Hort. ex Tan.' " # use with parseStr2lang
)

par(mar = rep(0, 4), oma = rep(0, 4))

plotIdiograms(dfChrSize = cleiocarpaChr,     # chr. size data.frame
  dfMarkPos = cleiocarpaMarks,   # mark position data.frame
  dfMarkColor = markStyleDF,     # mark style d.f.

  orderChr = "original",        # preserve order of chr. of d.f.
  chrId = "",                   # do not add chr. names

  addOTUName = FALSE,           # remove name of OTU
  chrIdPatternRem = "_.*",      # regex pattern for removal of names of chr.
  chrSpacing = 0.2,             # separ. among chr.
  chrColor = "dodgerblue",      # chr. color
  chromatids = FALSE,           # do not use separ. chromatids

  dotsAsOval = TRUE              # use oval shape instead of dots marks
  , legendWidth = .8             # legend item width
  , legendHeight = 3             # legend item height
  , markLabelSpacer = 2          # legend spacer
  , ruler = FALSE                # no ruler
  , chrIndex = ""                # no chr. index
  , morpho = ""                  # no morpho.
  , karIndex = FALSE             # no kar. ind.

  , leftNotesUp = notesdf        # data.frame with notes
  , parseStr2lang = TRUE         # use italics, see notesdf above
  , leftNotesUpTextSize = 1.3    # font size of notes
  , leftNotesUpPosX = 0          # pos. left notes x axis
  , leftNotesUpPosY = 1          # pos. left notes y axis

  , ylimBotMod = 0               # modify ylim bottom argument
  , xlimRightMod = 4             # modify right xlim
)

11.7 Citrus limon origin

With data from da-Costa-Silva et al. (2015), Mendes et al. (2016) and Carvalho et al. (2005)

11.7.1 Citrus reticulata (Parental 1)

data.frame of chr. sizes


# c. reticulata ----X---- c. aurantium
#                   |
#                c. limon


# c. reticulata

#
#   chr. size - arms in pixels
#

{
  citrusReticulata <- read.table(text = "
chrName shortArmSize longArmSize totalTrue
f 67 91  2.65
d 61 77  2.32
c 59 78  2.18
d 61 83  2.49
d 34 63  1.87
d 50 66  1.93
d 50 83  2.28
f 42 77  2.02
f 28 67  1.70", header = TRUE)

  citrusReticulata$pseudototal <- citrusReticulata$shortArmSize + citrusReticulata$longArmSize

  # pixel to micrometers
  citrusReticulata$shortArmSize <- citrusReticulata$shortArmSize / (citrusReticulata$pseudototal / citrusReticulata$totalTrue)
  citrusReticulata$longArmSize <- citrusReticulata$longArmSize / (citrusReticulata$pseudototal / citrusReticulata$totalTrue)

  citrusReticulata$chrName <- toupper(citrusReticulata$chrName)
  citrusReticulata$chrName <- make.uniqueIF(citrusReticulata$chrName)
  citrusReticulata$OTU <- "C. reticulata 'Cravo'"

}


Sort chromosomes


# sort chr. by name
citrusReticulata <- citrusReticulata[order(citrusReticulata$chrName), ]

# sort Ds by size
Ds <- citrusReticulata[which(citrusReticulata$chrName %in% grep("D", citrusReticulata$chrName, value = TRUE)
), ]
citrusReticulata[which(citrusReticulata$chrName %in% grep("D", citrusReticulata$chrName, value = TRUE)
), ] <- Ds[order(Ds$shortArmSize + Ds$longArmSize), ]

# sort Fs by size
Fs <- citrusReticulata[which(citrusReticulata$chrName %in% grep("F", citrusReticulata$chrName, value = TRUE)
), ]

citrusReticulata[which(citrusReticulata$chrName %in% grep("F", citrusReticulata$chrName, value = TRUE)), ] <-
  Fs[order(Fs$shortArmSize + Fs$longArmSize), ]

# add group column to show that each one is a pair
citrusReticulata$group <- 1:9


data.frame of bands


#
# c. reticulata bands
#

{
  citrusReticulataMarkPosDF <- citrusMarkPos(citrusReticulata)

  # remove CMA terminal from D
  citrusReticulataMarkPosDF <- citrusReticulataMarkPosDF[-which(citrusReticulataMarkPosDF$chrName == "D_3" &
    citrusReticulataMarkPosDF$markName == "CMA"
  ), ]

  # add marks in short arm of D

  Sr_D_3 <- citrusReticulata[which(citrusReticulata$chrName == "D_3"), ]$shortArmSize
  # 45S
  citrusReticulataMarkPosDF_D45S  <- data.frame(chrName = "D_3",
    chrRegion = "p",
    markName = "45S",
    markDistCen = Sr_D_3 - (.15 + .15 / 2),
    markSize = 0.15,
    OTU = unique(citrusReticulata$OTU)
  )

  # CMA
  citrusReticulataMarkPosDF_DCMA  <- data.frame(chrName = "D_3",
    chrRegion = "p",
    markName = "CMA",
    markDistCen = Sr_D_3 - .3,
    markSize = 0.3,
    OTU = unique(citrusReticulata$OTU)
  )

  # add 45S rDNA mark in short arm  of C
  citrusReticulataMarkPosDF_C45S  <- data.frame(chrName = "C",
    chrRegion = "p",
    markName = "45S",
    markDistCen = 0,
    markSize = 0.1,
    OTU = unique(citrusReticulata$OTU)
  )

  # fuse marks
  citrusReticulataMarkPosDF <- dplyr::bind_rows(citrusReticulataMarkPosDF,
    citrusReticulataMarkPosDF_D45S,
    citrusReticulataMarkPosDF_DCMA,
    citrusReticulataMarkPosDF_C45S
  )

  # change band sizes

  # D_1
  citrusReticulataMarkPosDF[which(citrusReticulataMarkPosDF$chrName == "D_1"), ]$markSize <- .75
  LAD_1 <- citrusReticulata[which(citrusReticulata$chrName == "D_1"), ]$longArmSize
  citrusReticulataMarkPosDF[which(citrusReticulataMarkPosDF$chrName == "D_1"), ]$markDistCen <-
    LAD_1 - .75

  # C short arm
  citrusReticulataMarkPosDF[which(citrusReticulataMarkPosDF$chrName == "C" &
    citrusReticulataMarkPosDF$markName == "CMA" &
    citrusReticulataMarkPosDF$chrRegion == "p"), ]$markSize <- .3

  SAC <- citrusReticulata[which(citrusReticulata$chrName == "C"), ]$shortArmSize

  citrusReticulataMarkPosDF[which(citrusReticulataMarkPosDF$chrName == "C" &
    citrusReticulataMarkPosDF$markName == "CMA" &
    citrusReticulataMarkPosDF$chrRegion == "p"
  ), ]$markDistCen <- SAC - .3

  # C LONG ARM
  citrusReticulataMarkPosDF[which(citrusReticulataMarkPosDF$chrName == "C" &
    citrusReticulataMarkPosDF$markName == "CMA" &
    citrusReticulataMarkPosDF$chrRegion == "q"), ]$markSize <- .4

  LAC <- citrusReticulata[which(citrusReticulata$chrName == "C"), ]$longArmSize

  citrusReticulataMarkPosDF[which(citrusReticulataMarkPosDF$chrName == "C" &
    citrusReticulataMarkPosDF$markName == "CMA" &
    citrusReticulataMarkPosDF$chrRegion == "q"
  ), ]$markDistCen <- LAC - .4


  # D_2
  citrusReticulataMarkPosDF[which(citrusReticulataMarkPosDF$chrName == "D_2"), ]$markSize <- .55
  LAD_2 <- citrusReticulata[which(citrusReticulata$chrName == "D_2"), ]$longArmSize
  citrusReticulataMarkPosDF[which(citrusReticulataMarkPosDF$chrName == "D_2"), ]$markDistCen <-
    LAD_2 - .55

  # D_4
  citrusReticulataMarkPosDF[which(citrusReticulataMarkPosDF$chrName == "D_4"), ]$markSize <- .6
  LAD_4 <- citrusReticulata[which(citrusReticulata$chrName == "D_4"), ]$longArmSize
  citrusReticulataMarkPosDF[which(citrusReticulataMarkPosDF$chrName == "D_4"), ]$markDistCen <-
    LAD_4 - .6

  # D_5
  citrusReticulataMarkPosDF[which(citrusReticulataMarkPosDF$chrName == "D_5"), ]$markSize <- .7
  LAD_5 <- citrusReticulata[which(citrusReticulata$chrName == "D_5"), ]$longArmSize
  citrusReticulataMarkPosDF[which(citrusReticulataMarkPosDF$chrName == "D_5"), ]$markDistCen <-
    LAD_5 - .7
}

11.7.2 C. aurantium ‘common’ (Parental 2)

data.frame of chr. sizes


# From Mendes et al. 2016

# 1a + 1b + 1C + 8D + 7F

{
  #
  # chr .sizes
  #

  citrusaurantium <- read.table(text = "
chrName shortArmSize longArmSize
f   1.43333333333333    2.06666666666667
f   1.36666666666667    1.83333333333333
d   1.3 1.66666666666667
d   1.13333333333333    1.46666666666667
d   1   1.6
a   1.3 2
d   1.36666666666667    1.8
d   1.06666666666667    1.63333333333333
d   0.733333333333333   1.36666666666667
f   0.833333333333333   1.36666666666667
d   1.13333333333333    1.33333333333333
c   1.16666666666667    1.66666666666667
d   1.06666666666667    1.8
b   1   1.83333333333333
f   0.966666666666667   1.6
f   0.8 1.36666666666667
f   0.633333333333333   1.43333333333333
f   0.733333333333333   1.3
", header = TRUE)

  # modify chr. names
  citrusaurantium$chrName <- toupper(citrusaurantium$chrName)
  citrusaurantium$chrName <- make.uniqueIF(citrusaurantium$chrName)

  # add column
  citrusaurantium$OTU <- "C. aurantium 'common'"

}


Order pairs based in BAC markers (not shown here - different to 45S / 5S rDNA )


{
  # confirmed pairs
  customOrder <- c("A", "D_3", "C", "D_7")

  customOrder <- c(customOrder, sort(setdiff(citrusaurantium$chrName, customOrder)))

  # sort
  citrusaurantium$chrName <- factor(citrusaurantium$chrName, levels = customOrder)
  citrusaurantium <- citrusaurantium[order(citrusaurantium$chrName), ]


  # sort Ds by size

  Ds <- citrusaurantium[which(citrusaurantium$chrName %in% grep("D", citrusaurantium$chrName, value = TRUE) &
    !citrusaurantium$chrName %in% c("D_3", "D_7")), ]
  citrusaurantium[which(citrusaurantium$chrName %in% grep("D", citrusaurantium$chrName, value = TRUE) &
    !citrusaurantium$chrName %in% c("D_3", "D_7")), ] <- Ds[order(Ds$shortArmSize + Ds$longArmSize), ]

  # sort Fs by size
  Fs <- citrusaurantium[which(citrusaurantium$chrName %in% grep("F", citrusaurantium$chrName, value = TRUE)
  ), ]
  citrusaurantium[which(citrusaurantium$chrName %in% grep("F", citrusaurantium$chrName, value = TRUE)), ] <-
    Fs[order(Fs$shortArmSize + Fs$longArmSize), ]

  # pairs:

  groups <- c(1, 1, 2, 2)
  citrusaurantium$group <- c(groups, rep(NA, 18 - length(groups)))

  # secondary name
  citrusaurantium$chrNameUp <- 1:18

}


data.frame of bands

Option 1. Write from scratch:

{
  citrusaurantiumMarkPosDF <- read.table(text = "
  chrName chrRegion markName markDistCen markSize
  A           p      CMA   0.73    0.570
  A           p      CMA   0.00    0.350
  A           q      CMA   1.23    0.770
  B           p      CMA   0.00    0.350
  B           q      CMA   0.86    0.970
  C           p      CMA   0.74    0.430
  C           q      CMA   1.07    0.600
  D_1         q      CMA   0.60    1.070
  D_2         q      CMA   0.84    0.630
  D_3         q      CMA   1.07    0.530
  D_4         q      CMA   1.07    0.730
  D_5         q      CMA   0.86    0.770
  D_7         q      CMA   0.46    0.870
  D_8         q      CMA   0.90    0.900
  B           p      45S   0.09    0.175
  A           p      45S   0.09    0.175
  D_6         p      45S   0.58    0.100
  D_6         p      CMA   0.53    0.200
  ", header = TRUE)

  citrusaurantiumMarkPosDF$OTU <- "C. aurantium 'common'"
}
# this is equivalent to the following section


Option 2. Use functions:

{
  #
  # CMA bands
  #
  citrusaurantiumMarkPosDF <- citrusMarkPos(citrusaurantium)

  # add 45S in B
  citrusaurantiumMarkPosDF <- markOverCMA(citrusaurantiumMarkPosDF,
    chrType = "B",
    chrRegion = "p",
    markName = "45S")

  # add 45S in A p prox
  citrusaurantiumMarkPosDF <- markOverCMA(citrusaurantiumMarkPosDF,
    chrType = "A",
    chrRegion = "p",
    markName = "45S")


  # D_6

  # change D (D_6) band from long to short
  SA_D_6 <- citrusaurantium[which(citrusaurantium$chrName == "D_6"), ]$shortArmSize

  # 45S in short
  citrusaurantiumMarkPosDF_D45S  <- data.frame(chrName = "D_6",
    chrRegion = "p",
    markName = "45S",
    markDistCen = SA_D_6 - .15,
    markSize = 0.1,
    OTU = unique(citrusaurantium$OTU)
  )

  # CMA in short
  citrusaurantiumMarkPosDF_DCMA  <- data.frame(chrName = "D_6",
    chrRegion = "p",
    markName = "CMA",
    markDistCen = SA_D_6 - .2,
    markSize = 0.2,
    OTU = unique(citrusaurantium$OTU)
  )

  # remove CMA terminal from D_6 long
  citrusaurantiumMarkPosDF <- citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName != "D_6"), ]

  # change mark sizes according to publication

  # D_1 band

  # change mark size
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "D_1"), ]$markSize <- 1.07

  # arm size
  LAD_1 <- citrusaurantium[which(citrusaurantium$chrName == "D_1"), ]$longArmSize

  # change mark dist. to cen.
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "D_1"), ]$markDistCen <-
    LAD_1 - 1.07

  # D_2
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "D_2"), ]$markSize <- 0.63
  LAD_2 <- citrusaurantium[which(citrusaurantium$chrName == "D_2"), ]$longArmSize
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "D_2"), ]$markDistCen <-
    LAD_2 - .63

  # D_3
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "D_3"), ]$markSize <- 0.53
  LAD_3 <- citrusaurantium[which(citrusaurantium$chrName == "D_3"), ]$longArmSize
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "D_3"), ]$markDistCen <-
    LAD_3 - .53

  # A p ter
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "A" &
    citrusaurantiumMarkPosDF$markDistCen == 1.05), ]$markSize <- 0.57
  SAA <- citrusaurantium[which(citrusaurantium$chrName == "A"), ]$shortArmSize

  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "A" &
    citrusaurantiumMarkPosDF$markDistCen == 1.05), ]$markDistCen <-
    SAA - .57

  # A q
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "A" &
    citrusaurantiumMarkPosDF$chrRegion == "q"), ]$markSize <- 0.77
  LAA <- citrusaurantium[which(citrusaurantium$chrName == "A"), ]$longArmSize

  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "A" &
    citrusaurantiumMarkPosDF$chrRegion == "q"), ]$markDistCen <-
    LAA - .77

  # D_4
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "D_4"), ]$markSize <- 0.73
  LAD_4 <- citrusaurantium[which(citrusaurantium$chrName == "D_4"), ]$longArmSize
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "D_4"), ]$markDistCen <-
    LAD_4 - .73

  # D_5
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "D_5"), ]$markSize <- 0.77
  LAD_5 <- citrusaurantium[which(citrusaurantium$chrName == "D_5"), ]$longArmSize
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "D_5"), ]$markDistCen <-
    LAD_5 - .77

  # D_7
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "D_7"), ]$markSize <- 0.87
  LAD_7 <- citrusaurantium[which(citrusaurantium$chrName == "D_7"), ]$longArmSize
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "D_7"), ]$markDistCen <-
    LAD_7 - .87

  # C p
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "C" &
    citrusaurantiumMarkPosDF$chrRegion == "p"), ]$markSize <- .43
  SAC <- citrusaurantium[which(citrusaurantium$chrName == "C"), ]$shortArmSize
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "C" &
    citrusaurantiumMarkPosDF$chrRegion == "p"), ]$markDistCen <-
    SAC - .43

  # C q
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "C" &
    citrusaurantiumMarkPosDF$chrRegion == "q"), ]$markSize <- .6
  LAC <- citrusaurantium[which(citrusaurantium$chrName == "C"), ]$longArmSize
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "C" &
    citrusaurantiumMarkPosDF$chrRegion == "q"), ]$markDistCen <-
    LAC - .6

  # D_8
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "D_8"), ]$markSize <- 0.9
  LAD_8 <- citrusaurantium[which(citrusaurantium$chrName == "D_8"), ]$longArmSize
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "D_8"), ]$markDistCen <-
    LAD_8 - .9

  # B q
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "B" &
    citrusaurantiumMarkPosDF$chrRegion == "q"), ]$markSize <- .97
  LAB <- citrusaurantium[which(citrusaurantium$chrName == "B"), ]$longArmSize
  citrusaurantiumMarkPosDF[which(citrusaurantiumMarkPosDF$chrName == "B" &
    citrusaurantiumMarkPosDF$chrRegion == "q"), ]$markDistCen <-
    LAB - .97

  # fuse marks
  citrusaurantiumMarkPosDF <- dplyr::bind_rows(citrusaurantiumMarkPosDF,
    citrusaurantiumMarkPosDF_D45S,
    citrusaurantiumMarkPosDF_DCMA
  )
}

11.7.3 C. limon


# from: Carvalho 2005

# C. limon - 1B(45Sprox) + 1C + 8D + 1D(45S) + 5F + 1FL0 + 1FL+

{
  # data.frame of  chr. sizes

  citruslimon <- citrusSize(B = 1, C = 1, D = 9, F = 5, FL0 = 1, FL = 1,
    OTU = "C. limon")
  citruslimon

  # modify sizes

  citruslimon$shortArmSize[3] <- 1.1
  citruslimon$longArmSize[3] <- 1.5

  citruslimon$shortArmSize[4:5] <- 1.15
  citruslimon$longArmSize[4:5] <- 1.6

  citruslimon$shortArmSize[6:7] <- 1.1
  citruslimon$longArmSize[6:7] <- 1.6

  citruslimon$shortArmSize[8:9] <- 1.15
  citruslimon$longArmSize[8:9] <- 1.65

  citruslimon$shortArmSize[2] <- 1
  citruslimon$longArmSize[2] <- 1.6

  citruslimon$shortArmSize[12] <- 1
  citruslimon$longArmSize[12] <- 1.5

  citruslimon$shortArmSize[10:11] <- .95
  citruslimon$longArmSize[10:11] <- 1.4

  citruslimon$shortArmSize[13:14] <- 1
  citruslimon$longArmSize[13:14] <- 1.5

  citruslimon$shortArmSize[15:16] <- .95
  citruslimon$longArmSize[15:16] <- 1.3

  # sort Ds by size

  Ds <- citruslimon[which(citruslimon$chrName %in% grep("D", citruslimon$chrName, value = TRUE)
  ), ]

  citruslimon[which(citruslimon$chrName %in% grep("D", citruslimon$chrName, value = TRUE)
  ), ] <- Ds[order(Ds$shortArmSize + Ds$longArmSize), ]

  # sort Fs by size
  Fs <- citruslimon[which(citruslimon$chrName %in% grep("F", citruslimon$chrName, value = TRUE)
  ), ]

  citruslimon[which(citruslimon$chrName %in% grep("F", citruslimon$chrName, value = TRUE)), ] <-
    Fs[order(Fs$shortArmSize + Fs$longArmSize), ]


  # secondary chr. name
  citruslimon$chrNameUp <- 1:18

  #
  # data.frame of CMA band pos.
  #

  citruslimonMarkPosDF <- citrusMarkPos(citruslimon)
  head(citruslimonMarkPosDF)

  # marks with overlap with CMA
  # 45S in B, short arm

  citruslimonMarkPosDF <- markOverCMA(citruslimonMarkPosDF,
    chrType = "B",
    chrRegion = "p",
    markName = "45S")

  # 45S in D (D_1), long arm
  citruslimonMarkPosDF <- markOverCMA(citruslimonMarkPosDF,
    chrName = "D_1",
    chrRegion = "q",
    markName = "45S")

  # add mark from scratch (no overlap with CMA)

}

11.7.4 Merge data.frames from all OTUs


#
# data.frames of size - merge
#

threeSize    <- dplyr::bind_rows(citrusReticulata, citruslimon, citrusaurantium)

#
# data.frames of band pos. merge
#

threeMarkPos <- dplyr::bind_rows(citruslimonMarkPosDF, citrusaurantiumMarkPosDF, citrusReticulataMarkPosDF)


#
#   leftNotes with formulas
#

# formulas
limon      <- "1B + 1C + 9D + 5F + 1FL0 + 1FL+ [1B/45S, 1D/45S]"
aurantium  <- "1A + 1B + 1C + 8D + 7F [1A/45S, 1B/45S, 1D/45S]"
reticulata <- "2C + 10D + 6F [2C/45S, 2D/45S]"

leftNotesdf <- data.frame(OTU = unique(threeSize$OTU), note = c(reticulata, limon, aurantium))

# authors
notesdf <- data.frame(OTU = unique(threeSize$OTU),
  note = c("da-Costa-Silva et al. (2015)", "Carvalho et al. (2005)", "Mendes et al. (in prep.)")
)

# marks' style data.frame

markStyleDF   <- makedfMarkColorMycolors(
  unique(citrusReticulataMarkPosDF$markName), c("darkgoldenrod1", "chartreuse3")
)

markStyleDF$style <- c("square", "dots")

11.7.5 Plot

{
  svg("climon.svg", width = 12, height = 10)
  par(mar = rep(0, 4), oma = rep(0, 4))
  plotIdiograms(dfChrSize = threeSize,   # chr. size data.frame
    dfMarkPos = threeMarkPos, # mark position data.frame (inc. cen.)
    dfMarkColor = markStyleDF, # mark style d.f.

    orderChr = "original",   # order of chr. as in d.f.
    chrIdPatternRem = "_.*", # pattern to remove from chr. names
    karHeight = 2,           # karyotype height
    karHeiSpace = 6,         # height + separ. among karyot.

    chrSpacing = .20,       # separ. among chr.
    chrColor = "dodgerblue",
    distTextChr = .9        # distance text to chr.

    , legendWidth = .8       # legend item width
    , legendHeight = 3       # legend item height
    , markLabelSpacer = 2    # legend spacer
    , ruler = FALSE          # do not use ruler
    , chrIndex = ""          # do not print chr. index
    , morpho = ""            # do not print morphology
    , karIndex = FALSE       # do not print kar. index

    # ,colorBorderMark = "black"# color of border of marks
    , lwd.chr = 1             # border width

    , OTUfont = 3             # OTU name in italics

    , leftNotes = leftNotesdf # data.frame with notes (formula)
    , leftNotesTextSize = 1.3 # font size of notes
    , leftNotesPosX = 0      # horizontal pos. of formula
    , leftNotesPosY = 1      # vertical pos. of formula
    , notes = notesdf        # authors

    , classGroupName = "Pair" # name for groups
    , chrNameUp = TRUE        # use col. chrNameUp
    , classChrName = "Type"   # change default title of inferior name
    , classChrNameUp = "Chr." # change default title of upper name

    , ylimBotMod = 1         # modify ylim bottom argument
    , ylimTopMod = 0         # modify ylim top argument
    , xlimLeftMod = 2        # modify left xlim
    , xlimRightMod = 5       # modify right xlim

    , threshold = 40         # fixes shrinking of scale, needed because some chr. greater than 3.5 um
    , moveKarHor = "C. limon" # kar. to move to right
    , mkhValue = 5           # move cariótipo para direita
    , anchor = TRUE          # parental structure
    , moveAnchorV = 1        # move anchor
    , anchorVsizeF = .35     # anchor vertical size factor modifier
    , karSepar = FALSE       # modif. separ de karyo.
  )
  dev.off() # close svg
}

For a plot of GISH of Citrus, visit the GISH chapter