2015-01-10 3 views
3

Я пытаюсь скопировать графики этого сайта https://gjabel.wordpress.com/2014/03/28/circular-migration-flow-plots-in-r/ с использованием библиотеки r "circlize". К сожалению у меня есть две проблемы:R circlize - поля на графике и области для печати

Прежде всего, я получил предупреждение для всех областей печати (то есть Note: 1 point is out of plotting region in sector 'Mexico', track '1'). Я думал, что проблема в том, что в circos.text и circos.axis, так как я использовал их вместе с direction, что является устаревшей функцией. Но также с использованием facing вместо direction проблема остается. Поэтому, я думаю, я не понял смысла этого предупреждения. У вас есть какие-то намеки, чтобы помочь мне?

Кроме того, на моем участке ссылки были очень далеки от сегментов. Таким образом, я попытался уменьшить track.margin, которые решают проблему, но теперь имена сегментов находятся за пределами поля, и я не могу их визуализировать. Есть ли лучший способ решить эту проблему?

Это то, что я написал до сих пор (который почти полностью взят с этого сайта https://github.com/null2/globalmigration)

library("circlize") 
library("plyr") 
library("migest") 
#load data 
m<-read.table(system.file("science", "country_custom.txt", package = "migest"), skip=2, stringsAsFactors=FALSE) 
#1)a data.frame to store information on each segment of the circle to be plotted 
df1<-m[,1:3] 
names(df1)<-c("order","rgb","region") 
df1$region<-gsub("\\.", "\n", df1$region) 
#2) a matrix containing the flow data (in this example only 28 countries) 
m<-m[,-(1:3)]/1e05 
m<-as.matrix(m) 
dimnames(m)<-list(orig=df1$region,dest=df1$region) 
#sort order of data.frame and matrix for plotting in circos  
df1<-arrange(df1, order) #reordering a data frame by its columns 
df1$region <- factor(df1$region, levels=df1$region) 
m<-m[levels(df1$region),levels(df1$region)] 
#define ranges of circos sectors and their colors (both of the sectors and the links) 
#determine the length of segments on the outside of the plot. 
df1$xmin <- 0 
df1$xmax <- rowSums(m)+colSums(m) #inflows+outflows 
#set the colour names for segments and flows 
n<-nrow(df1) 
df1 <- cbind(df1, matrix(as.numeric(unlist(strsplit(df1$rgb,","))),nrow=n, byrow=TRUE)) 
names(df1)[ncol(df1)-2:0]<-c("r","g","b") 
df1$rcol<-rgb(df1$r, df1$g, df1$b, max = 255) 
df1$lcol<-rgb(df1$r, df1$g, df1$b, alpha=200, max = 255) 
##plot sectors 
windows() 
par(mar=rep(0,4)) 
circos.clear() 
#1)basic circos graphic parameters 
circos.par(cell.padding=c(0,0,0,0), track.margin=c(0,0.01), start.degree = 90, gap.degree =4) 
#2)sector details 
circos.initialize(factors = df1$region, xlim = cbind(df1$xmin, df1$xmax)) 
#3)plot sectors 
circos.trackPlotRegion(ylim = c(0, 1), factors = df1$region, track.height=0.1, 
     panel.fun = function(x, y) { 
     #select details of current sector 
     name = get.cell.meta.data("sector.index") 
     i = get.cell.meta.data("sector.numeric.index") 
     xlim = get.cell.meta.data("xlim") 
     ylim = get.cell.meta.data("ylim") 

     #text direction (dd) and adjusmtents (aa) 
     theta = circlize(mean(xlim), 1.3)[1, 1] %% 360 
     dd <- ifelse(theta < 90 || theta > 270, "vertical_right", "vertical_left") 
     aa = c(1, 0.5) 
     if(theta < 90 || theta > 270) aa =c(0, 0.5) 

     #plot country labels 
     circos.text(x=mean(xlim), y=1.7, labels=name, direction = dd, 
     cex=0.6,adj = aa) 
     #circos.text(x=mean(xlim), y=2, labels=name, facing = "bending",cex=0.6)    

     #plot main sector 
     circos.rect(xleft=xlim[1], ybottom=ylim[1], xright=xlim[2], ytop=ylim[2], 
     col = df1$rcol[i], border=df1$rcol[i]) 

     #blank in part of main sector 
     circos.rect(xleft=xlim[1], ybottom=ylim[1], xright=xlim[2]-rowSums(m)[i], ytop=ylim[1]+0.3, 
     col = "white", border = "white") 

     #white line all the way around 
     circos.rect(xleft=xlim[1], ybottom=0.3, xright=xlim[2], ytop=0.32, col = "white", border = "white") 

     #plot axis 
     #NOTE: Ticks indicate the number of migrants in 100s. 
     circos.axis(labels.cex=0.6, direction = "outside", major.at=seq(from=0,to=floor(df1$xmax)[i],by=5), 
     minor.ticks=1, labels.away.percentage = 0.15) 
     }) 

Большое спасибо за вашу помощь.

EDIT: Я добавляю вторую часть скрипта, так как кажется, что необходимо решить вторую проблему.

#plot links 
#create a new dataframe containing the long form of the matrix m 
#add sum values to df1, marking the x-position of the first links out (sum1) and in (sum2). Updated for further links in loop below. 
df1$sum1 <- colSums(m) #outflows 
df1$sum2 <- numeric(n) 
#create a data.frame of the flow matrix sorted by flow size, to allow largest flow plotted first 
df2<-cbind(as.data.frame(m),orig=rownames(m), stringsAsFactors=FALSE) 
#long matrix 
df2<-reshape(df2, idvar="orig", varying=list(1:n), direction="long", timevar="dest", time=rownames(m), v.names = "m") 
df2<-arrange(df2,desc(m)) 
#keep only the largest flows to avoid clutter 
df2<-subset(df2, m>quantile(m,0.925)) 
#plot links 
for(k in 1:nrow(df2)){ 
require("circlize") 
#i,j reference of flow matrix 
#note: you are selecting the states in region1 according to the edgelist in region2 
i<-match(df2$orig[k],df1$region) 
j<-match(df2$dest[k],df1$region) 
#plot link 
#sector.index1=sender 
#point1=size of the base of the link at the origin 
#We set the origin segment to start at the current sum of outflows from the sender country (df1$sum1[i])  
#We set the end of the segment outflow equal to the total outflows from the sender country, plus the flow from the edge we considered 
circos.link(sector.index1=df1$region[i], point1=c(df1$sum1[i], df1$sum1[i] + abs(m[i, j])), 
sector.index2=df1$region[j], point2=c(df1$sum2[j], df1$sum2[j] + abs(m[i, j])), 
col = df1$lcol[i]) #, top.ratio==0.66, top.ratio.low==0.67) 
#note: The height and thickness of the link at its mid-point is determined by the top.ratio and the top.ratio.low argument 
#update sum1 and sum2 for use when plotting the next link 
df1$sum1[i] = df1$sum1[i] + abs(m[i, j]) 
df1$sum2[j] = df1$sum2[j] + abs(m[i, j]) 
} 
+0

Похоже, что этот код не является центральным в вопросе. Было бы здорово, если бы вы могли уменьшить его до небольшого, воспроизводимого примера, например. путем удаления всего кода, который подготавливает 'df1', и включая вывод' dput (df1) 'вместо этого. – jbaums

+1

Привет, jbaums, спасибо за ваш комментарий. Я отредактировал сценарий в сообщении, так что теперь он должен быть более сфокусированным. Теперь это касается только части сегмента, поскольку ссылки не нужны. Что касается воспроизводимости, я знаю, что dput() обычно является хорошим решением, но в этом случае потребуется более 50 строк, тогда как я использовал только 25 строк. Но я могу изменить его, если вы думаете, что это лучше. – sezonzo

+0

Извините, я не понял, что вы загружали файл, включенный в пакет. Приветствия. – jbaums

ответ

3

Первая проблема с сообщениями о заметках на самом деле не проблема. Вы все равно можете получить сюжет, который вы хотите, независимо от предупреждения. Вы можете подчинить сообщение, используя

circos.par(points.overflow.warning=FALSE) 

Вторая проблема связана с недавним обновлением пакета circlize. Вам нужно изменить поле дорожек из своих первоначальных настроек, добавляя

circos.par(track.margin=c(0,0)) 

circos.trackPlotRegion после команды и до ссылки рисуется через circos.link функции в цикле for.

Извините за проблемы. Я имею в виду обновить демо-файл в пакете migest некоторое время, но вроде забыл об этом в праздничные дни.

+0

Привет, gjabel, большое вам спасибо за все усилия, которые вы предоставляете в обмене своей работой. Я отредактировал сообщение, чтобы каждый мог участвовать в обсуждении, также прочитав ссылку на скрипт. Я попытался использовать circos.par, но, вероятно, я действительно не понимал, как управлять им, так как мой результат не изменился. Не могли бы вы сказать, как мне точно вставить этот скрипт? – sezonzo

+0

@sezonzo Вам просто нужно добавить строку в ответе выше к вашему сценарию (перед циклом). Полный рабочий сценарий теперь находится на моей странице github: https://github.com/gjabel/migest/blob/master/demo/cfplot_nat.R – gjabel

+1

Это сработало! Опять же, чем вы – sezonzo

7

Вы можете проверить chordDiagram() в текущей версии circlize. chordDiagram() - это гибкая функция, которая делает такую ​​диаграмму аккорда (т. Е. Круговой график со ссылками внутри). Эта функция была введена в последних версиях circlize, и вам не нужно слишком много кода для самоопределения диаграммы аккордов. Существует также виньетка, поставляемая с пакетом, которая дает вам подробное представление о том, как создать простую или сложную диаграмму аккордов.

Быстрая демонстрация воспроизведения фигуры вы заинтересованы следующим образом:

mat = matrix(runif(36), 6) 
rownames(mat) = letters[1:6] 
colnames(mat) = letters[1:6] 

library(circlize) 
circos.par(gap.degree = 8) 
chordDiagram(mat, grid.col = 1:6, directional = TRUE, annotationTrack = "grid", 
    preAllocateTracks = list(list(track.height = 0.05), 
          list(track.height = 0.05))) 
circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) { 
    xlim = get.cell.meta.data("xlim") 
    ylim = get.cell.meta.data("ylim") 
    sector.index = get.cell.meta.data("sector.index") 
    circos.text(mean(xlim), mean(ylim), sector.index, facing = "inside", niceFacing = TRUE) 
}, bg.border = NA) 
circos.trackPlotRegion(track.index = 2, panel.fun = function(x, y) { 
    circos.axis("bottom", major.tick.percentage = 0.2, labels.cex = 0.4) 
}, bg.border = NA) 
circos.clear() 

enter image description here

1

Как автор объяснил here

«points.overflow.предупреждение "Поскольку каждая ячейка на самом деле не является реальной областью построения , а только обычным прямоугольником, она не устраняет точек, которые выводятся из области. Поэтому, если какие-то точки отсутствуют из области печати, circlize продолжит рисование точки и печать предупреждения. в некоторых случаях, нарисовать что-то из черчения области полезно, например, сделать некоторые легенды или текст. Установите это значение FALSE, чтобы отключить предупреждения.

по canvas.xlim и canvas.ylim (описано на той же странице выше), вы можете настроить свой холст, чтобы избежать, или j ust игнорирует предупреждение.

 Смежные вопросы

  • Нет связанных вопросов^_^