本节包含一些有关如何使数据可视化的想法。大多数内容来自他人撰写的书籍和帖子,但我将负责将其放在此处。


11.1 标签Labeling

图上的所有内容均应标记以下内容:

  • title-一个清晰的简短标题,使读者知道他们在看什么:性别与经验和工资之间的关系

  • subtitle -可选的第二个(较小的字体)标题,提供其他信息:2016-2018年

  • caption -数据的来源,资料来源:美国劳工部-www.bls.gov/bls/blswage.htm

  • axis labels s-x和y轴的标签

    • 简短但具有描述性
    • 包括计量单位
      • 发动机排量(立方英寸)
      • 生存时间(天)
      • 患者年龄(岁)
  • Legend -简短的标题和标签

    • 男性和女性 -不是0和1!
  • 线和条 -标记任何趋势线,注释线和误差线

基本上,读者应该能够理解您的图表,而不必费力浏览文本的各个段落。如有疑问,请向尚未阅读您的文章或海报的人展示您的数据可视化,并询问他们是否不清楚。


11.2 信噪比

在数据科学中,数据可视化的目的是传达信息。任何不支持此目标的内容都应减少或消除。


11.3 颜色选择

颜色的选择不仅仅是美观,选择有助于传达图中信息的颜色。

文章如何为您的数据可视化选择完美的色彩组合是一个很好的起点。

  • sequential - for plotting a quantitative variable that goes from low to high
  • diverging - for contrasting the extremes (low, medium, and high) of a quantitative variable
  • qualitative - for distinguishing among the levels of a categorical variable

上面的文章可以帮助您在这些方案中进行选择。另外,RColorBrewer包提供按这种方式分类的调色板。

其他需要记住的事情:

  • 确保文本清晰易读-避免在深色背景上使用深色文本,在浅色背景上使用浅色文本,以及颜色以不协调的方式发生冲突(例如,它们看起来很受伤!)。
  • 避免使用红色和绿色的组合-色盲的观众很难分辨这些颜色

11.4 y轴 scaling

根据缩放数字y轴的方式,您可以使效果显得庞大或微不足道。考虑以下示例,比较男性和女性助理教授的9个月薪水。 数据来自“学术工资”数据集。  

# load data
data(Salaries, package="carData")

# get means, standard deviations, and 95% confidence intervals for assistant professor salary by sex 
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
df <- Salaries %>%
  filter(rank == "AsstProf") %>%
  group_by(sex) %>%
  summarize(n = n(),
            mean = mean(salary), 
            sd = sd(salary),
            se = sd / sqrt(n),
            ci = qt(0.975, df = n - 1) * se)

df
## # A tibble: 2 x 6
##   sex        n   mean    sd    se    ci
##   <fct>  <int>  <dbl> <dbl> <dbl> <dbl>
## 1 Female    11 78050. 9372. 2826. 6296.
## 2 Male      56 81311. 7901. 1056. 2116.
# create and save the plot
library(ggplot2)
p <- ggplot(df, 
            aes(x = sex,
                y = mean)) +
  geom_point(size = 4) +
  geom_line(aes(group = 1)) +
  scale_y_continuous(limits = c(77000, 82000),
                     labels = scales::dollar) +
  labs(title = "Mean salary differences by gender",
       subtitle = "9-mo academic salary in 2007-2008",
       caption = paste("source: Fox J. and Weisberg, S. (2011)",
                       "An R Companion to Applied Regression,", 
                       "Second Edition Sage"),
       x = "Gender",
       y = "Salary")

p

First, let’s plot this with a y-axis going from 77,000 to 82,000.

# plot in a narrow range of y
p + scale_y_continuous(limits=c(77000, 82000))
## Scale for 'y' is already present. Adding another scale for 'y', which will
## replace the existing scale.

性别差异似乎很大。接下来,让我们以y轴从0到125,000绘制相同的数据。

# plot in a wide range of y
p + scale_y_continuous(limits = c(0, 125000))
## Scale for 'y' is already present. Adding another scale for 'y', which will
## replace the existing scale.

似乎没有性别差异!数据可视化的目的是要以最小的失真展示发现,这意味着为y轴应该选择合适的范围。

条形图应几乎总是从y = 0开始。对于其他图表,限制实际上取决于对值的预期范围的主题知识。我们还可以通过添加不确定性指标来改进图形。

df %>% 
  ggplot(aes(sex,mean)) +
  geom_point(size = 3,col = "red") +
  geom_errorbar(aes(ymin = mean - ci,ymax = mean + ci),width = 0.2,col = "steelblue") +
  geom_line(aes(group = 1))

p <- ggplot(df, 
            aes(x = sex, y = mean)) +
  geom_point(size = 4) +
  geom_line(aes(group = 1)) +
  scale_y_continuous(limits = c(70000, 85000),
                     labels = scales::dollar) +
  labs(title = "Mean salary differences by gender",
       subtitle = "9-mo academic salary in 2007-2008",
       caption = paste("source: Fox J. and Weisberg, S. (2011)",
                       "An R Companion to Applied Regression,", 
                       "Second Edition Sage"),
       x = "Gender",
       y = "Salary")

# plot with confidence limits
p +  geom_errorbar(aes(ymin = mean - ci, 
                       ymax = mean + ci), 
                       width = .1) +
  ggplot2::annotate("text", 
           label = "I-bars are 95% \nconfidence intervals", 
           x=2, 
           y=73500,
           size = 4) +
  theme(text = element_text(family = "Times New Roman"))

看看离散变量绘制线段,有意思哈哈

df %>% 
  ggplot(aes(sex,mean)) +
  geom_point(size = 3) +
  geom_segment(aes(x = 1,y = 78049.91,xend = 2,yend = 81311.46),size = 1)

df %>% 
  ggplot(aes(sex,mean)) +
  geom_point(size = 3) +
  geom_line(group = 1) +
  theme(text = element_text(family = "Times New Roman",face = "italic"))

11.5 属性

除非是你的数据,否则每个图表都应该有一个属性——一个引导读者找到数据来源的说明,这通常出现在图的标题中。

11.6 走的更远

如果您想了解更多关于ggplot2的信息,有几个很好的资源,包括:

  • the ggplot2 homepage
  • the book ggplot2: Elegenat Graphics for Data Anaysis (be sure to get the third edition)
  • the eBook R for Data Science - the data visualization chapter
  • the ggplot2 cheatsheet

全是免费!!!

如果您想了解更多关于数据可视化的内容,这里有一些有用的资源:

  • Harvard Business Reviews - Visualizations that really work
  • the website Information is Beautiful
  • the book Beautiful Data: The Stories Behind Elegant Data Solutions
  • the Wall Street Journal’s - Guide to Information Graphics
  • the book The Truthful Art

11.7 最后的笔记

随着现成数据的增长(或者我应该说泛滥?),数据可视化领域正在爆炸。激动人心的图形工具的可用性支持了这种爆炸式增长,这是一个学习和探索的好时机。享受吧!

LS0tDQp0aXRsZTogIuWIqeeUqFLov5vooYzmlbDmja7lj6/op4bljJbigJTigJTnrKzljYHkuIDnq6Dlu7rorq4v5pyA5L2z5YGa5rOV5Zu+Ig0KYXV0aG9yOiAiTEpKIg0KZGF0ZTogIjIwMjAvMy8yNSINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0Og0KICAgICAgY29sbGFwc2VkOiBmYWxzZQ0KICAgICAgc21vb3RoX3Njcm9sbDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICANCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSxmaWcuc2hvdyA9ICJob2xkIixmaWcuYWxpZ24gPSAiY2VudGVyIixjYWNoZSA9IFRSVUUpDQpgYGANCg0K5pys6IqC5YyF5ZCr5LiA5Lqb5pyJ5YWz5aaC5L2V5L2/5pWw5o2u5Y+v6KeG5YyW55qE5oOz5rOV44CC5aSn5aSa5pWw5YaF5a655p2l6Ieq5LuW5Lq65pKw5YaZ55qE5Lmm57GN5ZKM5biW5a2Q77yM5L2G5oiR5bCG6LSf6LSj5bCG5YW25pS+5Zyo5q2k5aSE44CCDQoNCi0tLQ0KDQojIyAxMS4xIOagh+etvkxhYmVsaW5nDQoNCuWbvuS4iueahOaJgOacieWGheWuueWdh+W6lOagh+iusOS7peS4i+WGheWuue+8mg0KDQoqIHRpdGxlLeS4gOS4qua4heaZsOeahOeugOefreagh+mimO+8jOS9v+ivu+iAheefpemBk+S7luS7rOWcqOeci+S7gOS5iO+8muaAp+WIq+S4jue7j+mqjOWSjOW3pei1hOS5i+mXtOeahOWFs+ezuw0KDQoqIHN1YnRpdGxlIC3lj6/pgInnmoTnrKzkuozkuKrvvIjovoPlsI/nmoTlrZfkvZPvvInmoIfpopjvvIzmj5Dkvpvlhbbku5bkv6Hmga/vvJoyMDE2LTIwMTjlubQNCg0KKiBjYXB0aW9uIC3mlbDmja7nmoTmnaXmupAs6LWE5paZ5p2l5rqQ77ya576O5Zu95Yqz5bel6YOoLXd3dy5ibHMuZ292L2Jscy9ibHN3YWdlLmh0bQ0KDQoqIGF4aXMgbGFiZWxzIHMteOWSjHnovbTnmoTmoIfnrb4NCiAgLSDnroDnn63kvYblhbfmnInmj4/ov7DmgKcNCiAgLSDljIXmi6zorqHph4/ljZXkvY0NCiAgICAgLSDlj5HliqjmnLrmjpLph4/vvIjnq4vmlrnoi7Hlr7jvvIkNCiAgICAgLSDnlJ/lrZjml7bpl7TvvIjlpKnvvIkNCiAgICAgLSDmgqPogIXlubTpvoTvvIjlsoHvvIkNCg0KKiBMZWdlbmQgLeeugOefreeahOagh+mimOWSjOagh+etvg0KICAtIOeUt+aAp+WSjOWls+aApyAt5LiN5pivMOWSjDHvvIENCiog57q/5ZKM5p2hIC3moIforrDku7vkvZXotovlir/nur/vvIzms6jph4rnur/lkozor6/lt67nur8NCg0K5Z+65pys5LiK77yM6K+76ICF5bqU6K+l6IO95aSf55CG6Kej5oKo55qE5Zu+6KGo77yM6ICM5LiN5b+F6LS55Yqb5rWP6KeI5paH5pys55qE5ZCE5Liq5q616JC944CC5aaC5pyJ55aR6Zeu77yM6K+35ZCR5bCa5pyq6ZiF6K+75oKo55qE5paH56ug5oiW5rW35oql55qE5Lq65bGV56S65oKo55qE5pWw5o2u5Y+v6KeG5YyW77yM5bm26K+i6Zeu5LuW5Lus5piv5ZCm5LiN5riF5qWa44CCDQoNCi0tLQ0KDQojIyAxMS4yIOS/oeWZquavlA0KDQrlnKjmlbDmja7np5HlrabkuK3vvIwqKuaVsOaNruWPr+inhuWMlueahOebrueahOaYr+S8oOi+vuS/oeaBryoq44CC5Lu75L2V5LiN5pSv5oyB5q2k55uu5qCH55qE5YaF5a656YO95bqU5YeP5bCR5oiW5raI6Zmk44CCDQoNCi0tLQ0KDQojIyAxMS4zIOminOiJsumAieaLqQ0KDQrpopzoibLnmoTpgInmi6nkuI3ku4Xku4XmmK/nvo7op4Is6YCJ5oup5pyJ5Yqp5LqO5Lyg6L6+5Zu+5Lit5L+h5oGv55qE6aKc6Imy44CCDQoNCuaWh+eroFvlpoLkvZXkuLrmgqjnmoTmlbDmja7lj6/op4bljJbpgInmi6nlroznvo7nmoToibLlvannu4TlkIhdKGh0dHBzOi8vYmxvZy5odWJzcG90LmNvbS9tYXJrZXRpbmcvY29sb3ItY29tYmluYXRpb24tZGF0YS12aXN1YWxpemF0aW9uKeaYr+S4gOS4quW+iOWlveeahOi1t+eCueOAgg0KDQoqIHNlcXVlbnRpYWwgLSBmb3IgcGxvdHRpbmcgYSBxdWFudGl0YXRpdmUgdmFyaWFibGUgdGhhdCBnb2VzIGZyb20gbG93IHRvIGhpZ2gNCiogZGl2ZXJnaW5nIC0gZm9yIGNvbnRyYXN0aW5nIHRoZSBleHRyZW1lcyAobG93LCBtZWRpdW0sIGFuZCBoaWdoKSBvZiBhIHF1YW50aXRhdGl2ZSB2YXJpYWJsZQ0KKiBxdWFsaXRhdGl2ZSAtIGZvciBkaXN0aW5ndWlzaGluZyBhbW9uZyB0aGUgbGV2ZWxzIG9mIGEgY2F0ZWdvcmljYWwgdmFyaWFibGUNCg0K5LiK6Z2i55qE5paH56ug5Y+v5Lul5biu5Yqp5oKo5Zyo6L+Z5Lqb5pa55qGI5Lit6L+b6KGM6YCJ5oup44CC5Y+m5aSW77yMKipSQ29sb3JCcmV3ZXLljIUqKuaPkOS+m+aMiei/meenjeaWueW8j+WIhuexu+eahOiwg+iJsuadv+OAgg0KDQrlhbbku5bpnIDopoHorrDkvY/nmoTkuovmg4U6DQoNCiog56Gu5L+d5paH5pys5riF5pmw5piT6K+7LSoq6YG/5YWN5Zyo5rex6Imy6IOM5pmv5LiK5L2/55So5rex6Imy5paH5pysKirvvIzlnKjmtYXoibLog4zmma/kuIrkvb/nlKjmtYXoibLmlofmnKzvvIzku6Xlj4rpopzoibLku6XkuI3ljY/osIPnmoTmlrnlvI/lj5HnlJ/lhrLnqoHvvIjkvovlpoLvvIzlroPku6znnIvotbfmnaXlvojlj5fkvKTvvIHvvInjgIINCiog6YG/5YWN5L2/55So57qi6Imy5ZKM57u/6Imy55qE57uE5ZCILeiJsuebsueahOinguS8l+W+iOmavuWIhui+qOi/meS6m+minOiJsg0KDQojIyAxMS40IHnovbQgc2NhbGluZw0KDQrmoLnmja7nvKnmlL7mlbDlrZd56L2055qE5pa55byP77yM5oKo5Y+v5Lul5L2/5pWI5p6c5pi+5b6X5bqe5aSn5oiW5b6u5LiN6Laz6YGT44CC6ICD6JmR5Lul5LiL56S65L6L77yM5q+U6L6D55S35oCn5ZKM5aWz5oCn5Yqp55CG5pWZ5o6I55qEOeS4quaciOiWquawtOOAgiDmlbDmja7mnaXoh6rigJzlrabmnK/lt6XotYTigJ3mlbDmja7pm4bjgIINCiAgwqAgDQpgYGB7cn0NCiMgbG9hZCBkYXRhDQpkYXRhKFNhbGFyaWVzLCBwYWNrYWdlPSJjYXJEYXRhIikNCg0KIyBnZXQgbWVhbnMsIHN0YW5kYXJkIGRldmlhdGlvbnMsIGFuZCA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbHMgZm9yIGFzc2lzdGFudCBwcm9mZXNzb3Igc2FsYXJ5IGJ5IHNleCANCmxpYnJhcnkoZHBseXIpDQpkZiA8LSBTYWxhcmllcyAlPiUNCiAgZmlsdGVyKHJhbmsgPT0gIkFzc3RQcm9mIikgJT4lDQogIGdyb3VwX2J5KHNleCkgJT4lDQogIHN1bW1hcml6ZShuID0gbigpLA0KICAgICAgICAgICAgbWVhbiA9IG1lYW4oc2FsYXJ5KSwgDQogICAgICAgICAgICBzZCA9IHNkKHNhbGFyeSksDQogICAgICAgICAgICBzZSA9IHNkIC8gc3FydChuKSwNCiAgICAgICAgICAgIGNpID0gcXQoMC45NzUsIGRmID0gbiAtIDEpICogc2UpDQoNCmRmDQpgYGANCg0KDQpgYGB7cn0NCiMgY3JlYXRlIGFuZCBzYXZlIHRoZSBwbG90DQpsaWJyYXJ5KGdncGxvdDIpDQpwIDwtIGdncGxvdChkZiwgDQogICAgICAgICAgICBhZXMoeCA9IHNleCwNCiAgICAgICAgICAgICAgICB5ID0gbWVhbikpICsNCiAgZ2VvbV9wb2ludChzaXplID0gNCkgKw0KICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gMSkpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoNzcwMDAsIDgyMDAwKSwNCiAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IHNjYWxlczo6ZG9sbGFyKSArDQogIGxhYnModGl0bGUgPSAiTWVhbiBzYWxhcnkgZGlmZmVyZW5jZXMgYnkgZ2VuZGVyIiwNCiAgICAgICBzdWJ0aXRsZSA9ICI5LW1vIGFjYWRlbWljIHNhbGFyeSBpbiAyMDA3LTIwMDgiLA0KICAgICAgIGNhcHRpb24gPSBwYXN0ZSgic291cmNlOiBGb3ggSi4gYW5kIFdlaXNiZXJnLCBTLiAoMjAxMSkiLA0KICAgICAgICAgICAgICAgICAgICAgICAiQW4gUiBDb21wYW5pb24gdG8gQXBwbGllZCBSZWdyZXNzaW9uLCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAiU2Vjb25kIEVkaXRpb24gU2FnZSIpLA0KICAgICAgIHggPSAiR2VuZGVyIiwNCiAgICAgICB5ID0gIlNhbGFyeSIpDQoNCnANCg0KYGBgDQoNCkZpcnN0LCBsZXTigJlzIHBsb3QgdGhpcyB3aXRoIGEgeS1heGlzIGdvaW5nIGZyb20gNzcsMDAwIHRvIDgyLDAwMC4NCg0KYGBge3J9DQojIHBsb3QgaW4gYSBuYXJyb3cgcmFuZ2Ugb2YgeQ0KcCArIHNjYWxlX3lfY29udGludW91cyhsaW1pdHM9Yyg3NzAwMCwgODIwMDApKQ0KYGBgDQoNCuaAp+WIq+W3ruW8guS8vOS5juW+iOWkp+OAguaOpeS4i+adpe+8jOiuqeaIkeS7rOS7pXnovbTku44w5YiwMTI1LDAwMOe7mOWItuebuOWQjOeahOaVsOaNruOAgg0KDQpgYGB7cn0NCiMgcGxvdCBpbiBhIHdpZGUgcmFuZ2Ugb2YgeQ0KcCArIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDEyNTAwMCkpDQpgYGANCg0K5Ly85LmO5rKh5pyJ5oCn5Yir5beu5byC77yB5pWw5o2u5Y+v6KeG5YyW55qE55uu55qE5piv6KaB5Lul5pyA5bCP55qE5aSx55yf5bGV56S65Y+R546w77yM6L+Z5oSP5ZGz552A5Li6eei9tOW6lOivpemAieaLqeWQiOmAgueahOiMg+WbtOOAgiANCg0KKirmnaHlvaLlm77lupTlh6DkuY7mgLvmmK/ku455ID0gMOW8gOWniyoq44CC5a+55LqO5YW25LuW5Zu+6KGo77yM6ZmQ5Yi25a6e6ZmF5LiK5Y+W5Yaz5LqO5a+55YC855qE6aKE5pyf6IyD5Zu055qE5Li76aKY55+l6K+G44CC5oiR5Lus6L+Y5Y+v5Lul6YCa6L+H5re75Yqg5LiN56Gu5a6a5oCn5oyH5qCH5p2l5pS56L+b5Zu+5b2i44CCDQoNCmBgYHtyfQ0KZGYgJT4lIA0KICBnZ3Bsb3QoYWVzKHNleCxtZWFuKSkgKw0KICBnZW9tX3BvaW50KHNpemUgPSAzLGNvbCA9ICJyZWQiKSArDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtZWFuIC0gY2kseW1heCA9IG1lYW4gKyBjaSksd2lkdGggPSAwLjIsY29sID0gInN0ZWVsYmx1ZSIpICsNCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IDEpKQ0KDQpwIDwtIGdncGxvdChkZiwgDQogICAgICAgICAgICBhZXMoeCA9IHNleCwgeSA9IG1lYW4pKSArDQogIGdlb21fcG9pbnQoc2l6ZSA9IDQpICsNCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IDEpKSArDQogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDcwMDAwLCA4NTAwMCksDQogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OmRvbGxhcikgKw0KICBsYWJzKHRpdGxlID0gIk1lYW4gc2FsYXJ5IGRpZmZlcmVuY2VzIGJ5IGdlbmRlciIsDQogICAgICAgc3VidGl0bGUgPSAiOS1tbyBhY2FkZW1pYyBzYWxhcnkgaW4gMjAwNy0yMDA4IiwNCiAgICAgICBjYXB0aW9uID0gcGFzdGUoInNvdXJjZTogRm94IEouIGFuZCBXZWlzYmVyZywgUy4gKDIwMTEpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgIkFuIFIgQ29tcGFuaW9uIHRvIEFwcGxpZWQgUmVncmVzc2lvbiwiLCANCiAgICAgICAgICAgICAgICAgICAgICAgIlNlY29uZCBFZGl0aW9uIFNhZ2UiKSwNCiAgICAgICB4ID0gIkdlbmRlciIsDQogICAgICAgeSA9ICJTYWxhcnkiKQ0KDQojIHBsb3Qgd2l0aCBjb25maWRlbmNlIGxpbWl0cw0KcCArICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWVhbiAtIGNpLCANCiAgICAgICAgICAgICAgICAgICAgICAgeW1heCA9IG1lYW4gKyBjaSksIA0KICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IC4xKSArDQogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgDQogICAgICAgICAgIGxhYmVsID0gIkktYmFycyBhcmUgOTUlIFxuY29uZmlkZW5jZSBpbnRlcnZhbHMiLCANCiAgICAgICAgICAgeD0yLCANCiAgICAgICAgICAgeT03MzUwMCwNCiAgICAgICAgICAgc2l6ZSA9IDQpICsNCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiVGltZXMgTmV3IFJvbWFuIikpDQpgYGANCg0K55yL55yL56a75pWj5Y+Y6YeP57uY5Yi257q/5q6177yM5pyJ5oSP5oCd5ZOI5ZOIDQoNCmBgYHtyfQ0KZGYgJT4lIA0KICBnZ3Bsb3QoYWVzKHNleCxtZWFuKSkgKw0KICBnZW9tX3BvaW50KHNpemUgPSAzKSArDQogIGdlb21fc2VnbWVudChhZXMoeCA9IDEseSA9IDc4MDQ5LjkxLHhlbmQgPSAyLHllbmQgPSA4MTMxMS40Niksc2l6ZSA9IDEpDQoNCmRmICU+JSANCiAgZ2dwbG90KGFlcyhzZXgsbWVhbikpICsNCiAgZ2VvbV9wb2ludChzaXplID0gMykgKw0KICBnZW9tX2xpbmUoZ3JvdXAgPSAxKSArDQogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gIlRpbWVzIE5ldyBSb21hbiIsZmFjZSA9ICJpdGFsaWMiKSkNCmBgYA0KDQojIyAxMS41IOWxnuaApw0KDQrpmaTpnZ7mmK/kvaDnmoTmlbDmja7vvIzlkKbliJnmr4/kuKrlm77ooajpg73lupTor6XmnInkuIDkuKrlsZ7mgKfigJTigJTkuIDkuKrlvJXlr7zor7vogIXmib7liLDmlbDmja7mnaXmupDnmoTor7TmmI7vvIzov5npgJrluLjlh7rnjrDlnKjlm77nmoTmoIfpopjkuK3jgIINCg0KIyMgMTEuNiDotbDnmoTmm7Tov5wNCg0K5aaC5p6c5oKo5oOz5LqG6Kej5pu05aSa5YWz5LqOZ2dwbG90MueahOS/oeaBr++8jOacieWHoOS4quW+iOWlveeahOi1hOa6kO+8jOWMheaLrDoNCg0KKiB0aGUgZ2dwbG90MiBob21lcGFnZQ0KKiB0aGUgYm9vayBnZ3Bsb3QyOiAqKkVsZWdlbmF0IEdyYXBoaWNzIGZvciBEYXRhIEFuYXlzaXMqKiAoYmUgc3VyZSB0byBnZXQgdGhlIHRoaXJkIGVkaXRpb24pDQoqIHRoZSBlQm9vayBSIGZvciBEYXRhIFNjaWVuY2UgLSB0aGUgZGF0YSB2aXN1YWxpemF0aW9uIGNoYXB0ZXINCiogdGhlIGdncGxvdDIgY2hlYXRzaGVldA0KDQrlhajmmK/lhY3otLnvvIHvvIHvvIENCg0K5aaC5p6c5oKo5oOz5LqG6Kej5pu05aSa5YWz5LqOKirmlbDmja7lj6/op4bljJYqKueahOWGheWuue+8jOi/memHjOacieS4gOS6m+acieeUqOeahOi1hOa6kDoNCg0KKiBIYXJ2YXJkIEJ1c2luZXNzIFJldmlld3MgLSAqKlZpc3VhbGl6YXRpb25zIHRoYXQgcmVhbGx5IHdvcmsqKg0KKiB0aGUgd2Vic2l0ZSAqKkluZm9ybWF0aW9uIGlzIEJlYXV0aWZ1bCoqDQoqIHRoZSBib29rICoqQmVhdXRpZnVsIERhdGE6IFRoZSBTdG9yaWVzIEJlaGluZCBFbGVnYW50IERhdGEgU29sdXRpb25zKioNCiogdGhlIFdhbGwgU3RyZWV0IEpvdXJuYWzigJlzIC0gKipHdWlkZSB0byBJbmZvcm1hdGlvbiBHcmFwaGljcyoqDQoqIHRoZSBib29rICoqVGhlIFRydXRoZnVsIEFydCoqDQoNCiMjIDExLjcg5pyA5ZCO55qE56yU6K6wDQoNCumaj+edgOeOsOaIkOaVsOaNrueahOWinumVvyjmiJbogIXmiJHlupTor6Xor7Tms5vmu6U/Ke+8jOaVsOaNruWPr+inhuWMlumihuWfn+ato+WcqOeIhueCuOOAgua/gOWKqOS6uuW/g+eahOWbvuW9ouW3peWFt+eahOWPr+eUqOaAp+aUr+aMgeS6hui/meenjeeIhueCuOW8j+WinumVvyzov5nmmK/kuIDkuKrlrabkuaDlkozmjqLntKLnmoTlpb3ml7bmnLrjgILkuqvlj5flkKchDQoNCg0K