网络图layout如何自定义

写在前面

在构造更加合适我们解决问题的网络图layout过程中,我学习到了一些有意思的数据排布。这里展示给大家。

多边形–五边形

library(tidyverse)

pentagon <- tibble(
x = accumulate(1:4, ~.x+cos(.y*2*pi/5), .init = 0),
y = accumulate(1:4, ~.x+sin(.y*2*pi/5), .init = 0),
xend = accumulate(2:5, ~.x+cos(.y*2*pi/5), .init = cos(2*pi/5)),
yend = accumulate(2:5, ~.x+sin(.y*2*pi/5), .init = sin(2*pi/5)))

ggplot(pentagon)+
geom_segment(aes(x=x, y=y, xend=xend, yend=yend))+
coord_equal()+
theme_void()

定义随意多边形

polygon <- function(n) {
tibble(
x = accumulate(1:(n-1), ~.x+cos(.y*2*pi/n), .init = 0),
y = accumulate(1:(n-1), ~.x+sin(.y*2*pi/n), .init = 0),
xend = accumulate(2:n, ~.x+cos(.y*2*pi/n), .init = cos(2*pi/n)),
yend = accumulate(2:n, ~.x+sin(.y*2*pi/n), .init = sin(2*pi/n)))
}

ggplot(polygon(6))+
geom_segment(aes(x=x, y=y, xend=xend, yend=yend))+
coord_equal()+
theme_void()

ggplot(polygon(7))+
geom_segment(aes(x=x, y=y, xend=xend, yend=yend))+
coord_equal()+
theme_void()

ggplot(polygon(8))+
geom_segment(aes(x=x, y=y, xend=xend, yend=yend))+
coord_equal()+
theme_void()

ggplot(polygon(9))+
geom_segment(aes(x=x, y=y, xend=xend, yend=yend))+
coord_equal()+
theme_void()

复杂多边形,用于网络嵌套结构

polygon(5) -> df1
df1 %>% mutate(angle = atan2(yend-y, xend-x)+pi/2,
x = 0.5*x+0.5*xend,
y = 0.5*y+0.5*yend,
xend = x+0.2*cos(angle),
yend = y+0.2*sin(angle)) %>%
select(x, y, xend, yend) -> df2
df1 %>% bind_rows(df2) -> df
ggplot(df)+
geom_segment(aes(x=x, y=y, xend=xend, yend=yend))+
coord_equal()+
theme_void()

polygon(5) -> df1
df1 %>% mutate(angle = atan2(yend-y, xend-x)+pi/2,
x = 0.5*x+0.5*xend,
y = 0.5*y+0.5*yend,
xend = x+0.2*cos(angle),
yend = y+0.2*sin(angle)) %>%
select(x, y, xend, yend) -> df2
df2 %>% mutate(
x=xend,
y=yend,
xend=lead(x, default=first(x)),
yend=lead(y, default=first(y))) %>%
select(x, y, xend, yend) -> df3
df1 %>% bind_rows(df2) %>% bind_rows(df3) -> df
ggplot(df)+
geom_segment(aes(x=x, y=y, xend=xend, yend=yend))+
coord_equal()+
theme_void()

我觉得三级嵌套已经足够了

mid_points <- function(d) {
d %>% mutate(
angle=atan2(yend-y, xend-x) + pi/2,
x=0.5*x+0.5*xend,
y=0.5*y+0.5*yend,
xend=x+0.2*cos(angle),
yend=y+0.2*sin(angle)) %>%
select(x, y, xend, yend)
}
con_points <- function(d) {
d %>% mutate(
x=xend,
y=yend,
xend=lead(x, default=first(x)),
yend=lead(y, default=first(y))) %>%
select(x, y, xend, yend)
}
polygon(5) -> df1
df2 <- mid_points(df1)
df3 <- con_points(df2)
df4 <- mid_points(df3)
df5 <- con_points(df4)
df1 %>%
bind_rows(df2) %>%
bind_rows(df3) %>%
bind_rows(df4) %>%
bind_rows(df5) -> df
ggplot(df)+
geom_segment(aes(x=x, y=y, xend=xend, yend=yend))+
coord_equal()+
theme_void()

mid_points <- function(d, p) {
d %>% mutate(
angle=atan2(yend-y, xend-x) + pi/2,
x=p*x+(1-p)*xend,
y=p*y+(1-p)*yend,
xend=x+0.2*cos(angle),
yend=y+0.2*sin(angle)) %>%
select(x, y, xend, yend)
}
edges <- 7
niter <- 6
polygon(edges) -> df1
accumulate(.f = function(old, y) {
if (y%%2==0) mid_points(old, 0.3) else con_points(old)
},
1:niter,
.init=df1) %>%
bind_rows() -> df
ggplot(df)+
geom_segment(aes(x=x, y=y, xend=xend, yend=yend))+
coord_equal()+
theme_void()

当然我不需要将其化画成花的话

mid_points <- function(d, p, a) {
d %>% mutate(
angle=atan2(yend-y, xend-x) + a,
x=p*x+(1-p)*xend,
y=p*y+(1-p)*yend,
xend=x+0.2*cos(angle),
yend=y+0.2*sin(angle)) %>%
select(x, y, xend, yend)
}
edges <- 7
niter <- 18
polygon(edges) -> df1
accumulate(.f = function(old, y) {
if (y%%2!=0) mid_points(old, 0.3, pi/5) else con_points(old)
},
1:niter,
.init=df1) %>%
bind_rows() -> df
ggplot(df)+
geom_segment(aes(x=x, y=y, xend=xend, yend=yend))+
coord_equal()+
theme_void()

mid_points <- function(d, p, a, i, FUN = function(x) x) {
d %>% mutate(
angle=atan2(yend-y, xend-x) + a,
radius=FUN(i),
x=p*x+(1-p)*xend,
y=p*y+(1-p)*yend,
xend=x+radius*cos(angle),
yend=y+radius*sin(angle)) %>%
select(x, y, xend, yend)
}

edges <- 7
niter <- 18
polygon(edges) -> df1
accumulate(.f = function(old, y) {
if (y%%2!=0) mid_points(old, 0.3, pi/5, y) else con_points(old)
},
1:niter,
.init=df1) %>%
bind_rows() -> df
ggplot(df)+
geom_segment(aes(x=x, y=y, xend=xend, yend=yend))+
coord_equal()+
theme_void()

edges <- 7
niter <- 250
step <- 2
polygon(edges) -> df1
accumulate(.f = function(old, y) {
if (y%%step!=0) mid_points(old, 0.3, pi/5, y) else con_points(old)
},
1:niter,
.init=df1) %>%
bind_rows() -> df
ggplot(df)+
geom_curve(aes(x=x, y=y, xend=xend, yend=yend),
curvature = 0,
color="black",
alpha=0.1)+
coord_equal()+
theme(legend.position = "none",
panel.background = element_rect(fill="white"),
plot.background = element_rect(fill="white"),
axis.ticks = element_blank(),
panel.grid = element_blank(),
axis.title = element_blank(),
axis.text = element_blank())

library(tidyverse)

# This function creates the segments of the original polygon
polygon <- function(n) {
tibble(
x = accumulate(1:(n-1), ~.x+cos(.y*2*pi/n), .init = 0),
y = accumulate(1:(n-1), ~.x+sin(.y*2*pi/n), .init = 0),
xend = accumulate(2:n, ~.x+cos(.y*2*pi/n), .init = cos(2*pi/n)),
yend = accumulate(2:n, ~.x+sin(.y*2*pi/n), .init = sin(2*pi/n)))
}

# This function creates segments from some mid-point of the edges
mid_points <- function(d, p, a, i, FUN = ratio_f) {
d %>% mutate(
angle=atan2(yend-y, xend-x) + a,
radius=FUN(i),
x=p*x+(1-p)*xend,
y=p*y+(1-p)*yend,
xend=x+radius*cos(angle),
yend=y+radius*sin(angle)) %>%
select(x, y, xend, yend)
}

# This function connect the ending points of mid-segments
con_points <- function(d) {
d %>% mutate(
x=xend,
y=yend,
xend=lead(x, default=first(x)),
yend=lead(y, default=first(y))) %>%
select(x, y, xend, yend)
}

edges <- 3 # Number of edges of the original polygon
niter <- 250 # Number of iterations
pond <- 0.24 # Weight to calculate the point on the middle of each edge
step <- 13 # No of times to draw mid-segments before connect ending points
alph <- 0.25 # transparency of curves in geom_curve
angle <- 0.6 # angle of mid-segment with the edge
curv <- 0.1 # Curvature of curves
line_color <- "black" # Color of curves in geom_curve
back_color <- "white" # Background of the ggplot
ratio_f <- function(x) {sin(x)} # To calculate the longitude of mid-segments

# Generation on the fly of the dataset
accumulate(.f = function(old, y) {
if (y%%step!=0) mid_points(old, pond, angle, y) else con_points(old)
}, 1:niter,
.init=polygon(edges)) %>% bind_rows() -> df

# Plot
ggplot(df)+
geom_curve(aes(x=x, y=y, xend=xend, yend=yend),
curvature = curv,
color=line_color,
alpha=alph)+
coord_equal()+
theme(legend.position = "none",
panel.background = element_rect(fill=back_color),
plot.background = element_rect(fill=back_color),
axis.ticks = element_blank(),
panel.grid = element_blank(),
axis.title = element_blank(),
axis.text = element_blank())

reference

如果大家兴趣,可以到此处查看更多用法,但是到现在为为止,我们已经足够用了。

https://fronkonstin.com/tag/ggplot2/

(0)

相关推荐

  • ggdag:DAG和因果图

    近几年来,因果推断同时受到多个学科的重视,是最火热的研究方向之一.因果图(或称路径图)是研究因果关系的一个有效的辅助性工具.借助因果图可以分析因果关系,将复杂问题图形化.本文介绍一个用来绘制因果图的R ...

  • 跟着Nature Genetics 学画图:R语言ggplot2画箱线图(boxplot)展示D s...

    简介:R语言统计与绘图公众号目前致力于分享医学统计与R绘图知识,手把手教你使用R语言绘制基线特征表.KM生存曲线.森林图.ROC曲线等.每天一篇精彩R语言推文教程,手把手带你入门R语言绘图. 今天推文 ...

  • 自定义View(九)-View的工作原理- View的layout()和draw()

    作者:志先生_ 地址:https://www.jianshu.com/p/cb8e6c568b50 声明:本文是 志先生_ 原创投稿,转发等请联系原作者授权. 前言 上一节我们将View的测量流程理的 ...

  • 通过excel条件格式和自定义两种方法动态标记文本色彩,简单好用

    通过excel条件格式和自定义两种方法动态标记文本色彩,简单好用

  • 当纤薄遇上镂空,它是规则自定义者

    三年前的夏天,我去瑞士参加一年一度的蒙特勒爵士音乐节,空气中弥漫着萨克斯和钢琴的味道,疫情之前,每年有超过二十万乐迷赶到日内瓦湖边,听音乐喝啤酒,惬意放松. 2021年10月,蒙特勒音乐节将从日内瓦湖 ...

  • 自定义板块添加颜色以及自动选股设置

    之前上篇文章已经简单介绍了下如何给股票池添加自定义的颜色,其实就是设置自定义板块颜色就可以了,但是还有不少人不太清楚,所以就单独开一篇详细介绍下. 首先在给自定义板块添加颜色之前,先介绍下自动选股设置 ...

  • 自定义EndNote的输出样式(output style)

    EndNote是一种常用文献管理软件,由于其对Word.Page以及中文的良好支持,已经成为论文写作的必备工具之一. 这几天帮人修改毕业论文的格式,发现EndNote自带的输出样式都不能满足要求,于是 ...

  • 如何在 SAP Fiori Elements List Report 表格工具栏里增添新的自定义按钮

    如下图所示,这是 SAP Fiori Elements List Report 一个例子,我们想在表格工具栏里,新增一个自定义按钮: 实现方式 在 SAP Fiori Elements 项目工程里,修 ...

  • Visio中如何自定义快捷键?

    Visio中如何自定义快捷键? Visio中如何自定义快捷键? 展开

  • 带你玩转Word自定义功能区

    大家晚上好! 初识自定义功能区 首先,Word的功能区在哪? 如下图所示,即是Word的功能区:功能区有若干个选项卡构成,每个选项卡中根据功能分类包含若干命令. [自定义功能区]要在哪里设置? 路径: ...

  • .Net之配置文件自定义

    dotNET跨平台 今天 以下文章来源于鹏祥 ,作者AZRNG 鹏祥分享.Net相关技术文章,一起学习一起成长 前文讲获取配置文件内容的时候,是获取默认的appsettings.json配置文件的配置 ...