R Shiny 服务器未呈现正确的 ggplot 字体系列
R Shiny server not rendering correct ggplot font family
我正在尝试将漂亮的字体应用于 Shiny 应用程序中呈现的 ggplot。
使用 family="[fontname]" 在 RStudio(在同一台服务器上)中设置所需的字体可以正常工作。这里要求 "serif" 字体系列:
Image of correct ggplot font family rendering in rstudio
但是,当 ggplot 嵌入到 Shiny renderPlot({}) 函数中时,字体系列不会更改默认值。这里请求了相同的 "serif" 字体系列:
Image of incorrect ggplot font family rendering in Shiny app
字体大小和字体(粗体、斜体)的更改按预期工作。我已经在 RStudio 和闪亮的应用程序中使用 fonts() 和 pdfFonts() 检查了已安装的字体名称,然后尝试了列出的字体名称以及 "serif"、"sans" 和 "mono" ,都无济于事。我也试过 loadfonts().
一个最小的例子:
server.R
require(ggplot2)
require(ggthemes)
require(extrafont)
shinyServer(function(input, output) {
df <- data.frame(a=rnorm(100), b=rnorm(100))
output$the_plot <- renderPlot({
p <- ggplot(df, aes(x=a, y=b), environment=environment()) +
xlab("Alpha") +
ylab("Beta") +
geom_point() +
theme(text=element_text(family="serif", size=16))
print(p)
})
})
ui.R
library(shiny)
shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
h6("Font test")
),
mainPanel(
plotOutput("the_plot")
)
)
))
编辑: 有 a similar unanswered question 但寻求 pdf 而不是 png 输出。现在也尝试了 R 基础图形而不是 ggplot,结果相同。
作为解决方法,我使用 renderImage() 重新创建了大部分 renderPlot() 功能,如 this Shiny tutorial article 中所述。令人高兴的是,这呈现了大量的抗锯齿字体。希望这对其他人有用。
ui.R修改为
mainPanel(
imageOutput("myImage")
)
server.R
shinyServer(function(input, output, session) {
# A dynamically-sized plot
output$myImage <- renderImage({
# Read myImage's width and height. These are reactive values, so this
# expression will re-run whenever they change.
width <- session$clientData$output_myImage_width
height <- session$clientData$output_myImage_height
# For high-res displays, this will be greater than 1
pixelratio <- session$clientData$pixelratio
# A temp file to save the output.
outfile <- tempfile(fileext='.png')
# Generate the image file
png(outfile, width=width*pixelratio, height=height*pixelratio,
res=72*pixelratio)
plot(rnorm(100), rnorm(100), family="serif")
dev.off()
# Return a list containing the filename
list(src = outfile,
width = width,
height = height,
alt = "This is alternate text")
}, deleteFile = TRUE) # delete the temp file when finished
})
我正在尝试将漂亮的字体应用于 Shiny 应用程序中呈现的 ggplot。
使用 family="[fontname]" 在 RStudio(在同一台服务器上)中设置所需的字体可以正常工作。这里要求 "serif" 字体系列:
Image of correct ggplot font family rendering in rstudio
但是,当 ggplot 嵌入到 Shiny renderPlot({}) 函数中时,字体系列不会更改默认值。这里请求了相同的 "serif" 字体系列:
Image of incorrect ggplot font family rendering in Shiny app
字体大小和字体(粗体、斜体)的更改按预期工作。我已经在 RStudio 和闪亮的应用程序中使用 fonts() 和 pdfFonts() 检查了已安装的字体名称,然后尝试了列出的字体名称以及 "serif"、"sans" 和 "mono" ,都无济于事。我也试过 loadfonts().
一个最小的例子:
server.R
require(ggplot2)
require(ggthemes)
require(extrafont)
shinyServer(function(input, output) {
df <- data.frame(a=rnorm(100), b=rnorm(100))
output$the_plot <- renderPlot({
p <- ggplot(df, aes(x=a, y=b), environment=environment()) +
xlab("Alpha") +
ylab("Beta") +
geom_point() +
theme(text=element_text(family="serif", size=16))
print(p)
})
})
ui.R
library(shiny)
shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
h6("Font test")
),
mainPanel(
plotOutput("the_plot")
)
)
))
编辑: 有 a similar unanswered question 但寻求 pdf 而不是 png 输出。现在也尝试了 R 基础图形而不是 ggplot,结果相同。
作为解决方法,我使用 renderImage() 重新创建了大部分 renderPlot() 功能,如 this Shiny tutorial article 中所述。令人高兴的是,这呈现了大量的抗锯齿字体。希望这对其他人有用。
ui.R修改为
mainPanel(
imageOutput("myImage")
)
server.R
shinyServer(function(input, output, session) {
# A dynamically-sized plot
output$myImage <- renderImage({
# Read myImage's width and height. These are reactive values, so this
# expression will re-run whenever they change.
width <- session$clientData$output_myImage_width
height <- session$clientData$output_myImage_height
# For high-res displays, this will be greater than 1
pixelratio <- session$clientData$pixelratio
# A temp file to save the output.
outfile <- tempfile(fileext='.png')
# Generate the image file
png(outfile, width=width*pixelratio, height=height*pixelratio,
res=72*pixelratio)
plot(rnorm(100), rnorm(100), family="serif")
dev.off()
# Return a list containing the filename
list(src = outfile,
width = width,
height = height,
alt = "This is alternate text")
}, deleteFile = TRUE) # delete the temp file when finished
})