我正在开发这个闪亮的应用程序并定期在线更新它。自然地,我在本地处理它并每隔一段时间上传一次,以检查一切是否运行顺利。但是我遇到了这个问题,我似乎无法克服它。
我在应用程序上使用了一种名为 Source Code Pro 的自定义(Google)字体,因此整个应用程序都使用这种字体,包括图表。(为了简单起见,我故意没有在最小可重现示例中更改下载按钮的字体。)字体是使用showtext
包获取的,并通过运行font_add_google("Source Code Pro")
.
这些图表是用 生成的ggplot2
,然后我ggplotly(...)
用来生成一个图表,plotly
最后完成剩下的工作。图形本身是通过一个名为的用户定义函数生成的,该函数返回一个使用作为输入的数据 ( ) 和一些颜色 ( ),以及一个指示是否下载输出的附加参数(默认值)。这会在图表中添加一个图例(由于绘图工具提示,应用程序上显示的图表中不需要图例,但这在将图表下载为 PNG 时自然不起作用)。plotlyOutput
renderPlotly
returnChart
ggplot
sample_data
color_ids
download = F
在本地运行应用程序并单击下载按钮时,下载的图形的字体是 Source Code Pro,但在 shinyapps.io 服务器上运行应用程序时不是这种情况。(最初,它也会在本地失败,但使用Cairo
修复该问题的包)。我已经研究过这个解决方案,但它似乎无法解决问题。无论如何,我认为问题不在于 Ubuntu,因为自定义字体确实适用plotly
于应用程序上显示的图。
非常感谢您对此的任何想法。
在线应用程序可以在这里找到。
代码以与下面完全相同的顺序在同一个文件中运行,但为了便于阅读,我将其拆分。
加载包,初始化数据:
library(ggplot2)
library(tidyverse)
library(showtext)
library(Cairo)
library(shiny)
library(plotly)
library(viridis)
library(PerformanceAnalytics)
options(shiny.usecairo=T)
font_add_google("Source Code Pro")
sample_return1 = c(0.0866, 0.2254, 0.0079, -0.0006, 0.0216,
-0.0210, -0.0992, 0.0219, 0.0430, -0.0388,
0.2031, 0.0254,-0.0293, 0.0227, 0.0809,
0.0129, 0.0024, 0.0361, 0.0047, 0.0292,
0.0228,-0.0067, 0.0056, 0.0116,-0.0087,
0.0662, 0.1083, 0.0269, 0.0479,-0.0294,
-0.0329, 0.0104,-0.1716, 0.1194, 0.0152,
0.0389,-0.0026,-0.0381, 0.0568,-0.0873,
0.0797, 0.0141, 0.0112, 0.0145,-0.0278,
0.0395,-0.0164, 0.1176,-0.0232, 0.0236,
0.0306, 0.0210, 0.0333,-0.1140,-0.0780,
-0.0490, 0.0270, 0.0200, 0.1140, 0.1110)
sample_return2 = c(0.0336, 0.0891,-0.0096, 0.0211, 0.0483,
-0.0869, 0.0575, 0.1442,-0.0911,-0.0413,
-0.1383, 0.1542, 0.1088,-0.0886, 0.1515,
-0.1050, 0.0244, 0.2322, 0.0269,-0.0011,
0.0065, 0.1001, 0.0962,-0.0750, 0.0594,
0.0416, 0.0344,-0.0705,-0.0063,-0.1437,
-0.0054, 0.0131,-0.0147, 0.0331, 0.0303,
-0.0237,-0.0301, 0.0095,-0.0048, 0.0012,
0.0141, 0.0285, 0.0106,-0.0319, 0.0722,
0.0161,-0.0082,-0.0043, 0.0068,-0.0189,
-0.0065,-0.0400, 0.0136, 0.0125,-0.0076,
-0.0380, 0.0189, 0.0309,-0.0065, 0.0223,
0.0084,-0.0049,-0.0337, 0.0137, 0.0115,
-0.0093,-0.0025, 0.0025, 0.0042)
sample_dates1 = as.Date(c("2015-09-30", "2015-10-31", "2015-11-30",
"2015-12-31", "2016-01-31", "2016-02-29",
"2016-03-31", "2016-04-30", "2016-05-31",
"2016-06-30", "2016-07-31", "2016-08-31",
"2016-09-30", "2016-10-31", "2016-11-30",
"2016-12-31", "2017-01-31", "2017-02-28",
"2017-03-31", "2017-04-30", "2017-05-31",
"2017-06-30", "2017-07-31", "2017-08-31",
"2017-09-30", "2017-10-31", "2017-11-30",
"2017-12-31", "2018-01-31", "2018-02-28",
"2018-03-31", "2018-04-30", "2018-05-31",
"2018-06-30", "2018-07-31", "2018-08-31",
"2018-09-30", "2018-10-31", "2018-11-30",
"2018-12-31", "2019-01-31", "2019-02-28",
"2019-03-31", "2019-04-30", "2019-05-31",
"2019-06-30", "2019-07-31", "2019-08-31",
"2019-09-30", "2019-10-31", "2019-11-30",
"2019-12-31", "2020-01-31", "2020-02-29",
"2020-03-31", "2020-04-30", "2020-05-31",
"2020-06-30", "2020-07-31", "2020-08-31"))
sample_dates2 = as.Date(c( "2015-01-31", "2015-02-28", "2015-03-31",
"2015-04-30", "2015-05-31", "2015-06-30",
"2015-07-31", "2015-08-31", "2015-09-30",
"2015-10-31", "2015-11-30", "2015-12-31",
"2016-01-31", "2016-02-29", "2016-03-31",
"2016-04-30", "2016-05-31", "2016-06-30",
"2016-07-31", "2016-08-31", "2016-09-30",
"2016-10-31", "2016-11-30", "2016-12-31",
"2017-01-31", "2017-02-28", "2017-03-31",
"2017-04-30", "2017-05-31", "2017-06-30",
"2017-07-31", "2017-08-31", "2017-09-30",
"2017-10-31", "2017-11-30", "2017-12-31",
"2018-01-31", "2018-02-28", "2018-03-31",
"2018-04-30", "2018-05-31", "2018-06-30",
"2018-07-31", "2018-08-31", "2018-09-30",
"2018-10-31", "2018-11-30", "2018-12-31",
"2019-01-31", "2019-02-28", "2019-03-31",
"2019-04-30", "2019-05-31", "2019-06-30",
"2019-07-31", "2019-08-31", "2019-09-30",
"2019-10-31", "2019-11-30", "2019-12-31",
"2020-01-31", "2020-02-29", "2020-03-31",
"2020-04-30", "2020-05-31", "2020-06-30",
"2020-07-31", "2020-08-31", "2020-09-30"))
sample_name = c(rep("Quantamental", length(sample_return1)),
rep("St. Gallen", length(sample_return2)))
sample_data = data.frame(Date = c(sample_dates1, sample_dates2),
Return = c(sample_return1, sample_return2),
Program = sample_name)
color_ids = viridis(2)
returnChart
功能:
returnChart <- function(sample_data, color_ids, download = F){
p <- ggplot(data = sample_data,
aes(x = Date, y = Return, color = Program, group = Program,
text = paste0("Program: ", Program, "\n",
"Return: ", round(100*Return, 1), "%\n",
"Date: ", as.character(as.yearmon(Date)), "\n"))) +
geom_line() +
theme_bw() +
scale_y_continuous(labels=scales::percent) +
scale_color_manual(name = "Program", values = color_ids) +
theme(axis.title.x = element_text(family = "Source Code Pro"),
axis.title.y = element_text(family = "Source Code Pro"),
axis.text.x = element_text(family = "Source Code Pro"),
axis.text.y = element_text(family = "Source Code Pro"))
if (download == T){
p <- p +
theme(legend.position = "bottom",
legend.title = element_text(size = 8, family = "Source Code Pro"),
legend.text = element_text(size = 6, family = "Source Code Pro")) +
guides(color=guide_legend(nrow=ceiling(length(unique(sample_data$Program))/2),
byrow=TRUE, override.aes = list(size = 0.5)))
}
return(p)
}
闪亮的应用程序:
ui <- shinyUI(
mainPanel(
plotlyOutput("returnPlot"),
downloadButton("downloadReturn", "Download")
)
)
server <- shinyServer(function(input, output, session){
output$returnPlot <- renderPlotly({
p <- returnChart(sample_data, color_ids)
p <- p +
theme(legend.position = "none") +
theme(legend.title = element_blank())
ggplotly(p, tooltip = c("text")) %>%
config(modeBarButtonsToRemove = list("toImage"))
})
output$downloadReturn <- downloadHandler(
filename = function(){
"Return_Graph.png"
},
content = function(file) {
png(file, width = 16, height = 9, units = 'cm', res = 300,
type = "cairo")
print(returnChart(sample_data, color_ids, download = T))
dev.off()
},
contentType = 'image/png'
)
})
shinyApp(server = server, ui = ui)