如何在Linux/Fedora 31的R语言中修复度符号显示不正确的问题

9

我使用以下代码制作地图:

ggplot() + geom_sf()

该地图显示正常,但是度数符号显示不正确,如下图所示。

Corner of map with wrong degree sign

在Stack Overflow上给出的答案 - degree symbol incorrect in map axis labels - 对我没有帮助,因为我看到的是不同的符号。

更改字体也没有效果。

我尝试在另一个项目中使用renv从Github安装当前版本的sf(0.9),但结果相同。

我正在使用Linux系统,Fedora 31。

要复制此问题:

library("ggplot2")
library("sf")
nc <- st_read(system.file("shape/nc.shp", package="sf"))

ggplot() +
  geom_sf(data = nc)

2019-03-15更新

该问题并非特定于ggplot / geom_sf; 如评论中提到的那样,我使用plot.new(); text(0.5,0.5, bquote(120*degree*N), cex=5)时遇到相同的问题。 additional example of wrong degree sign

另外,为了澄清,我没有与?X11()帮助文档中详细描述的Wine相关的问题。 如果在我的终端中运行fc-match Symbol,我会得到:

StandardSymbolsPS.t1:“Standard Symbols PS”“正常”

更新2019-03-19

在新的Fedora 31和Fedora 32 beta安装中进行了确认。 可能是Fedora的问题。

我尝试使用不同的语言环境(包括例如“en_US.UTF-8”或“German”)和设备(例如cairo_pdf()cairo_ps()),结果相同。

X11.options()显示类型为“cairo”(将其更改为Xlib或dbcairo不会更改结果)。

使用dww在下面的答案中提出的TestChars()函数显示如下: test

但是,如果我使用knitr将其编织为pdf,则会获得大多数符号,包括°。

test from pdf

如果我编织为html,则会出现通常的乱码。

2020-03-20更新

正如@jpmam1所建议的那样,这似乎与pango中的回归有关,可以通过降级pango来暂时修复。 但是,降级pango会破坏操作系统的其他核心部分,例如nautilus

我在Fedora上开了一个bug:https://bugzilla.redhat.com/show_bug.cgi?id=1815128


4
你能否测试一下这是否实际上是ggplot/sf问题。更可能源于R中的plotmath或其他地方。如果运行 plot.new(); text(0.5,0.5, bquote(120*degree*N), cex=5),你会得到什么?请注意不要改变原来的意思。 - dww
1
你说得对,我也遇到了同样的问题... 我会在一秒钟内更新问题。 - giocomai
2
当您直接调用Unicode字符时,会打印出什么符号? 例如:plot.new(); text(0.5,0.5, bquote(paste("120", "\u00B0", "N", sep = "")), cex=5) - jared_mamrot
1
@jpmam1 正确的°符号,与预期完全一致。 - giocomai
1
这是一个绘图问题还是在导出时发生的?当我在Ubuntu上保存带有重音字符的文件时,遇到了类似的问题;我通过执行pdf.options(encoding = 'ISOLatin2')来解决它。 - Jindra Lacko
当我在视图窗格中绘制图形或使用cairo_pdf()保存时会出现这种情况,但在Rmd文件中使用knitr时则不会发生。如果我进行knit操作,则一切看起来都很好。 - giocomai
3个回答

10
这里有两种使用 R (ver3.6.3 2020-02-29) / R Studio (ver1.2.5033) 在 Fedora 31 VirtualBox VM 上解决问题的方法:
1)使用自定义比例尺插入 Unicode 字符以生成正确的符号(根据您的经/纬度包括 N/S 或 E/W)。
#install.packages("ggplot2")
#install.packages("sf")
library("ggplot2")
library("sf")

nc <- st_read(system.file("shape/nc.shp", package="sf"))

ggplot() +
  geom_sf(data = nc) +
  scale_x_continuous(labels = function(x) paste0(x, '\u00B0', "W")) +
  scale_y_continuous(labels = function(x) paste0(x, '\u00B0', "N"))

2)降级pango库。在Fedora 31中,升级了pango到1.44版本,由于从Freetype到HarfBuzz的转换,影响了位图字体(如默认的R-Studio字体)。降级该软件包可以修复系统范围内特殊字符的渲染问题。这也应该同样解决Fedora 32中的问题(未经测试)。

sudo dnf downgrade --releasever 30 pango-1.43.0-4.fc30.x86_64

这只是一个解决方法,而不是真正的解决方案。当然,使用自定义比例尺可以解决这个问题,正如在问题链接的SO答案中提到的那样。它也无法保留坐标中必要的N/S和E/W符号。当然,通过进一步的定制和if语句,这个问题可以得到解决,但这并不是一个完美的解决方案。 - giocomai
非常感谢您的更新,看起来很棒。我会把这个问题提供给上游注意。如果没有更好的选择,赏金就放在这里。 - giocomai
不幸的是,这不是可行的解决方案,因为降级pango会破坏“nautilus” - “nautilus:符号查找错误:nautilus:未定义的符号:pango_attr_insert_hyphens_new! - giocomai

3
事实证明,这种错误是由于R本身符号的遗留使用所致。
这可能会在R本身上游修复: https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17748 该问题引用了我针对 Fedora 开放反馈后开放的下游问题: https://bugzilla.redhat.com/show_bug.cgi?id=1815128 Iñaki Ucar 在 R 邮件列表上发布了一个可行的解决方案: https://stat.ethz.ch/pipermail/r-devel/2020-March/079185.html 这里为了参考将其复制如下:
$ sudo dnf install gdouros-symbola-fonts

Then add the following to /etc/fonts/local.conf (system-wide) or ~/.fonts.conf (just for your user):

<fontconfig>
<match target="pattern">
 <test name="family"><string>Symbol</string></test>
 <edit name="family" mode="prepend" binding="same">
   <string>Symbola</string>
 </edit>
</match>
</fontconfig>

Now you should see this:

$ fc-match Symbol
Symbola.ttf: "Symbola" "Regular"

and symbols should render correctly.

再次感谢Iñaki Ucar提供的解决方案。

感谢所有为此问题提供答案并协助排除故障的人。希望这个问题能够在R核心本身中得到解决。


3
这不是一个答案,而是一些需要尝试的诊断方法。这些方法太长无法在评论中说明。
请注意,“奇怪的符号”是指当指定字体中没有该符号时显示出来的符号。
在进行诊断之前,请注意从?plotmath中:
- 在类Unix操作系统上:在UTF-8语言环境下,可以输入任何Unicode字符,也可以使用\uxxxx或\Uxxxxxxxx转义序列输入字符。但问题是图形设备是否能够显示该字符。在X11设备上,使用cairo可能有最广泛的字符范围:请参阅它的帮助页面以了解如何安装附加字体。这通常可用于粗体或斜体显示希腊字母。 - 在非UTF-8语言环境中,通常不支持不属于当前编码语言的符号。
现在有一些要尝试的事情来调查原因:

1. 获取有关您本地设置的信息

Sys.getlocale()

2. 查看默认的X11设置:

X11.options()

我们特别关注 type,以查看 x11 设备是否正在使用 cairo。如果没有,请尝试在 X11.options() 中设置 cairo 选项,看看是否有帮助。

3. 要查看可用的字符,请输入以下内容:

TestChars <- function(...)
{
  info = l10n_info()
  r <- c(32:126, 160:254)
  par(pty = "s")
  plot(c(-1,10), c(20,260), type = "n", xlab = "", ylab = "", xaxs = "i", yaxs = "i")
  grid(11, 24, lty = 1)
  mtext(paste("MBCS:", info$MBCS, "  UTF8:", info$`UTF-8`, "  Latin:", info$`Latin-1`))
  for(i in r) try(points(i%%10, 10*i%/%10, pch = i, font = 5,...))
  points(6,170, col='red', cex=5)
}
TestChars()

在我的系统中,它看起来是这样的(请注意,我画了一个圆圈突出显示符号176,这正是你遇到问题的符号)。

输入图像描述

4. 查看其他图形设备上可用的符号

尝试在不同的设备上使用TestChars函数,查看它们是否有完整的符号集。例如:

cairo_pdf()
TestChars()
dev.off()

如果在尝试了这些方法之后,你仍然卡住了,请将诊断结果输入回你的问题中,以便它们能够帮助其他人解决问题。

这看起来非常有帮助,谢谢。快速回复...即使将语言环境设置为en_US.UTF-8或C,我基本上看不到这些符号(即我看到的是00B0),除了最后一个和点(第6列从下往上数第二个)。 Cairo是X11.options()中的类型,在更改设备时我看到了相同的情况。首先检查?plotmath,然后添加问题的详细信息。再次感谢! - giocomai
添加了问题的细节 - giocomai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接