You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修复Circlize弦图轴编号错位及Calibri粗体字体设置问题

R circlize包弦图自定义轴的两类问题解决方案

问题说明

使用circlize包绘制弦图、按固定间隔设置自定义主刻度时,出现两类异常:

  • 轴标签位置错位:调整字体大小后,各扇区外侧轴标签向内偏移,偏移程度随字体增大而提升,出现0刻度脱离对应刻度标记、C/D/J等扇区轴标签内移重叠的问题
  • 字体配置不生效:通过extrafonts、showtext包加载Calibri字体后,无法在绘图中正常调用该字体,也无法实现粗体效果

原始复现代码

示例邻接矩阵

#sample matrix
A<-c(4680,0,0,0,0,0,0,0,0,0)
B<-c(109,23323,0,0,0,0,0,0,0,0)
C<-c(9,12,5405,0,0,0,0,0,0,0)
D<-c(19,25,26,4615,0,0,0,0,0,0)
E<-c(108,816,32,38,5511,0,0,0,0,0)
F_1<-c(50,319,67,55,202,18198,0,0,0,0)
G<-c(15,11,8,178,11,18,38279,0,0,0)
H<-c(24,180,22,39,171,212,14,10673,0,0)
I<-c(211,2378,18,28,1603,251,25,188,34458,0)
J<-c(162,1623,31,48,1003,370,34,265,5319,27235)
m <- rbind(A,B,C,D,E,F_1,G,H,I,J)
row.names(m) <- LETTERS[seq(1,10,1)]
colnames(m)<- LETTERS[seq(1,10,1)]

原始绘图代码

colfunc <- colorRampPalette(c("#856705", "#d3d3d3", "#113069"))
grid.col <- setNames(colfunc(10), LETTERS[seq(1,10,1)])
grid.col

library(showtext); library(circlize)
  #my attempt to load the correct font but I am unsure how to call the font within circlize.
    
font_add(family = "Calibri", regular = "C:/Windows/Fonts/calibri.ttf", italic ="C:/Windows/Fonts/calibrii.ttf", bold =  "C:/Windows/Fonts/calibrib.ttf", bolditalic = "C:/Windows/Fonts/calibriz.ttf")
circos.clear()
  
showtext_auto()
    
circos.par(start.degree = 90, gap.degree = 5)
par(family = "Calibri") #tried to set the family to "Calibri" 
    
chordDiagram(m/1000,
             transparency = 0.5,
             grid.col = grid.col,
             annotationTrack = "grid",
             self.link = 1,
             link.lwd = 0.5,    # Line width
             link.lty = 1, 
             link.border = "light grey",
             annotationTrackHeight = mm_h(10))
    
    
for(si in get.all.sector.index()) {
  circos.axis(h = 'top',
              major.at = c(0,5,10,15,20,25,30,35,40,45,50),
              labels = c(0,5,10,15,20,25,30,35,40,45,50),
              minor.ticks = 4,
              labels.cex = fontsize(30),
              sector.index = si,
              track.index = 1,
              labels.niceFacing = TRUE)
      xlim = get.cell.meta.data("xlim", sector.index = si, track.index = 1)
      ylim = get.cell.meta.data("ylim", sector.index = si, track.index = 1)
    circos.text(mean(xlim),
                mean(ylim),
                si,
                sector.index = si,
                track.index = 1,
                niceFacing = TRUE,
                cex = fontsize(50),
                col = "white",
                font = par("Calibri"))
}

dev.copy(png, "test chord diagram.png", width = 5, height = 5, units = "cm", res = 600)
dev.off()
    circos.clear()

问题原因与修复方法

轴标签偏移问题

三个原因共同导致该异常:

  • 给所有扇区硬编码了统一的0-50刻度序列,但不同扇区的轴长度差异极大(比如C扇区总长度仅5.4左右),超出扇区范围的刻度值会强制渲染,导致刻度与标签位置错位
  • circos.axis默认标签偏移量适配小字体,大字体下没有预留足够外移距离,标签会向内挤压重叠
  • 使用dev.copy()导出图片时,会因屏幕设备与输出设备的分辨率映射差,导致元素位置偏移

修复操作:

  • 遍历每个扇区时,基于扇区自身的x轴范围生成对应间隔的刻度点,不要硬编码全局统一刻度
  • 在circos.axis()中添加labels.offset参数,根据字体大小设置合适的向外偏移值
  • 导出图片时先调用png()初始化输出设备,绘图完成后再调用dev.off(),不要用dev.copy()转存

字体失效问题

两个参数写法错误导致字体与粗体不生效:

  • circos.text()中的font参数是字重控制参数(取值1=常规、2=粗体、3=斜体、4=粗斜体),不能传入字体名称,原代码中font = par("Calibri")属于无效传参
  • circlize内部绘图会重置部分全局绘图参数,仅在开头用par(family=)设置全局字体无法传递到所有circlize渲染的元素中

修复操作:

  • 所有文本类元素(轴标签、扇区标识文字)显式传入family = "Calibri"指定字体
  • 需要粗体效果时,对应元素设置font = 2即可

修复后完整代码

colfunc <- colorRampPalette(c("#856705", "#d3d3d3", "#113069"))
grid.col <- setNames(colfunc(10), LETTERS[seq(1,10,1)])

library(showtext)
library(circlize)

# 加载Calibri字体,确认路径与本地文件匹配
font_add(family = "Calibri", 
         regular = "C:/Windows/Fonts/calibri.ttf", 
         italic ="C:/Windows/Fonts/calibrii.ttf", 
         bold =  "C:/Windows/Fonts/calibrib.ttf", 
         bolditalic = "C:/Windows/Fonts/calibriz.ttf")
circos.clear()
showtext_auto()

# 先初始化png输出设备,避免dev.copy导致的位置错位
png("test chord diagram.png", width = 5, height = 5, units = "cm", res = 600)

circos.par(start.degree = 90, gap.degree = 5)

chordDiagram(m/1000,
             transparency = 0.5,
             grid.col = grid.col,
             annotationTrack = "grid",
             self.link = 1,
             link.lwd = 0.5,
             link.lty = 1, 
             link.border = "light grey",
             annotationTrackHeight = mm_h(10))

for(si in get.all.sector.index()) {
  xlim = get.cell.meta.data("xlim", sector.index = si, track.index = 1)
  ylim = get.cell.meta.data("ylim", sector.index = si, track.index = 1)
  
  # 基于当前扇区的x轴范围生成5间隔的刻度,避免超出范围的无效刻度
  max_val <- ceiling(xlim[2]/5)*5
  major_ticks <- seq(0, max_val, 5)
  
  circos.axis(h = 'top',
              major.at = major_ticks,
              labels = major_ticks,
              minor.ticks = 4,
              labels.cex = fontsize(30),
              sector.index = si,
              track.index = 1,
              labels.niceFacing = TRUE,
              labels.offset = 0.3, # 大字体下增加标签向外偏移量,可根据实际效果调整数值
              labels.family = "Calibri") # 轴标签指定Calibri字体
  
  circos.text(mean(xlim),
              mean(ylim),
              si,
              sector.index = si,
              track.index = 1,
              niceFacing = TRUE,
              cex = fontsize(50),
              col = "white",
              family = "Calibri", # 指定字体
              font = 2) # 2对应粗体效果
}

dev.off()
circos.clear()

内容的提问来源于stack exchange,提问作者Dustin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 09:06:19