先看一下 matplotlib画峰峦图的效果
学习地址:https://matplotlib.org/matplotblog/posts/create-ridgeplots-in-matplotlib/
使用 JoyPy
JoyPy是一个基于 matplotlib+pandas 的单功能Python软件包,其目的仅在于:绘制Joyplots(又称脊线图)。
安装
1 | pip install -i http://pypi.douban.com/simple --trusted-host pypi.douban.com joypy |
看一下这个库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | def joyplot(data, column=None, by=None, grid=False, xlabelsize=None, xrot=None, ylabelsize=None, yrot=None, ax=None, figsize=None, hist=False, bins=10, fade=False, ylim='max', fill=True, linecolor=None, overlap=1, background=None, labels=None, xlabels=True, ylabels=True, range_style='all', x_range=None, title=None, colormap=None, **kwds): |
1 2 3 4 5 6 7 8 9 10 | import joypy import pandas as pd import numpy as np from matplotlib import pyplot as plt from matplotlib import cm import seaborn as sns iris = sns.load_dataset('iris') fig, axes = joypy.joyplot(iris)#连续值的列为一个"脊" |
1 2 | fig, axes = joypy.joyplot(iris, by="species", legend=True) #根据"Name"分组,每个Name是一行"脊",其中有多个,默认y轴一致 |
1 | fig, axes = joypy.joyplot(iris, by="species", ylim='own', legend=True)#使用各自y值 但是这就不可比 建议使用: |
1 | fig, axes = joypy.joyplot(iris, by="species", overlap=3) |
如果overlap=1,就等价于
1 | fig, axes = joypy.joyplot(iris, by="species")#根据"species"分组,每个species是一行"脊",其中有多个,默认y轴一致 |
1 2 3 | fig, axes = joypy.joyplot(iris, by="species", column="sepal_width", hist=True, bins=20, overlap=0, grid=False, legend=True) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import matplotlib.pyplot as plt plt.rcParams['font.family'] = ['Times New Roman'] colors = ['#791E94','#58C9B9','#519D9E','#D1B6E1'] fig,axs = joypy.joyplot(iris, by="species", fill=True, legend=True, alpha=.8, # range_style='own', ylim='own', xlabelsize=22, ylabelsize=22, grid='both', linewidth=.8, linecolor='k', figsize=(10,6), color=colors, ) ax = plt.gca() #设置x刻度 x = np.arange(6) xlabel=['a','b','c','d','e','f'] ax.set_xlim(left=-.5,right=5.5) ax.set_xticks(x) plt.savefig(r'C:\Users\Administrator\Desktop\p1.png', width=7,height=5,dpi=900,bbox_inches='tight') |
R语言-ggridges包 制作峰峦图
学习来源:https://wilkelab.org/ggridges/
安装
1 | install.packages("ggridges") |
加载包
1 2 3 4 5 6 | library(tidyverse) library(ggplot2) library(ggridges) library(viridisLite)# 安装 install.packages("viridisLite") library(viridis) library(RColorBrewer) |
密度脊线图
使用 geom_density_ridges
1 | ggplot(iris, aes(x = Sepal.Length, y = Species)) + geom_density_ridges() |
使用
1 2 | ggplot(iris, aes(x = Sepal.Length, y = Species)) + geom_density_ridges(rel_min_height = 0.01) |
可以使用
总而言之
scale参数控制的是密度图之间重叠的程度,值越小越分开,越大越重叠
1 2 3 | # scale = 0.9, not quite touching # 0.9 时最高点不会接触到上面的基线 ggplot(iris, aes(x = Sepal.Length, y = Species)) + geom_density_ridges(scale = 0.9) |
1 2 3 | # scale = 1, exactly touching # 1 时会刚好接触 ggplot(iris, aes(x = Sepal.Length, y = Species)) + geom_density_ridges(scale = 1) |
如果 scale 继续增大,则“峰峦”之间会相互重叠
其次,
The scaling is calculated separately per panel, so if we facet-wrap by species each density curve exactly touches the next higher baseline.
可以使用
1 2 | ggplot(iris, aes(x = Sepal.Length, y = Species)) + geom_density_ridges(scale = 1) + facet_wrap(~Species) |
沿x轴改变填充颜色
使用
geom_ridgeline_gradient
geom_density_ridges_gradient
不允许在填充中使用Alpha透明度
数据准备
使用lincoln_weather数据集(2016年在内布拉斯加州林肯的天气)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | head(lincoln_weather) # A tibble: 6 x 24 CST `Max Temperatur~ `Mean Temperatu~ `Min Temperatur~ `Max Dew Point ~ <chr> <int> <int> <int> <int> 1 2016~ 37 24 11 19 2 2016~ 41 23 5 22 3 2016~ 37 23 8 23 4 2016~ 30 17 4 24 5 2016~ 38 29 19 29 6 2016~ 34 33 32 33 # ... with 19 more variables: `Mean Dew Point [F]` <int>, `Min Dewpoint # [F]` <int>, `Max Humidity` <int>, `Mean Humidity` <int>, `Min # Humidity` <int>, `Max Sea Level Pressure [In]` <dbl>, `Mean Sea Level # Pressure [In]` <dbl>, `Min Sea Level Pressure [In]` <dbl>, `Max # Visibility [Miles]` <int>, `Mean Visibility [Miles]` <int>, `Min # Visibility [Miles]` <int>, `Max Wind Speed [MPH]` <int>, `Mean Wind # Speed[MPH]` <int>, `Max Gust Speed [MPH]` <int>, `Precipitation # [In]` <chr>, CloudCover <int>, Events <chr>, `WindDir [Degrees]` <int>, # Month <fct> |
这个数据集是366x24的结构
…
查看数据集全貌
1 | str(lincoln_weather) |
结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 'data.frame': 366 obs. of 24 variables: $ CST : chr "2016-1-1" "2016-1-2" "2016-1-3" "2016-1-4" ... $ Max.Temperature..F. : int 37 41 37 30 38 34 33 28 22 31 ... $ Mean.Temperature..F. : int 24 23 23 17 29 33 30 25 9 11 ... $ Min.Temperature..F. : int 11 5 8 4 19 32 27 22 -4 -9 ... $ Max.Dew.Point..F. : int 19 22 23 24 29 33 32 25 17 20 ... $ Mean.Dew.Point..F. : int 13 14 15 13 25 32 30 22 4 5 ... $ Min.Dewpoint..F. : int 8 4 8 2 19 29 25 18 -8 -13 ... $ Max.Humidity : int 88 100 92 92 96 100 100 92 87 87 ... $ Mean.Humidity : int 68 72 73 82 83 91 96 85 77 75 ... $ Min.Humidity : int 47 44 54 72 70 82 92 78 67 63 ... $ Max.Sea.Level.Pressure..In. : num 30.5 30.4 30.5 30.5 30.2 ... $ Mean.Sea.Level.Pressure..In.: num 30.4 30.3 30.4 30.4 30.1 ... $ Min.Sea.Level.Pressure..In. : num 30.3 30.2 30.3 30.2 30 ... $ Max.Visibility..Miles. : int 10 10 10 10 10 10 9 10 10 10 ... $ Mean.Visibility..Miles. : int 10 10 10 9 8 4 3 6 9 10 ... $ Min.Visibility..Miles. : int 10 10 10 6 5 0 0 2 5 10 ... $ Max.Wind.Speed..MPH. : int 20 15 13 17 22 16 16 25 25 10 ... $ Mean.Wind.Speed.MPH. : int 9 6 5 7 13 7 7 16 14 5 ... $ Max.Gust.Speed..MPH. : int 23 18 14 23 28 21 21 32 28 12 ... $ Precipitation..In. : chr "0" "0" "0" "0" ... $ CloudCover : int 0 0 0 1 4 8 8 8 5 0 ... $ Events : chr NA NA NA NA ... $ WindDir..Degrees. : int 280 312 330 155 178 167 7 338 340 268 ... $ Month : Factor w/ 12 levels "December","November",..: 12 12 12 12 12 12 12 12 12 12 ... |
大致了解数据集后,开始绘图
使用geom_density_ridges_gradient,参数如下
1 2 3 4 5 6 7 8 9 10 11 12 | geom_density_ridges_gradient( mapping = NULL, data = NULL, stat = "density_ridges", position = "points_sina", panel_scaling = TRUE, na.rm = TRUE, gradient_lwd = 0.5, show.legend = NA, inherit.aes = TRUE, ... ) |
绘图代码
注意:这里
官网给出的解释是:
要绘制峰峦图,需要将计算出的x值(stat(x))映射到填充美学上,而不是使用原始变量 ,如
之所以如此,是因为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | ggplot(lincoln_weather, # 美学映射 x轴 y轴 渐变 aes( x=`Mean Temperature [F]`, y=`Month`, # 使用x进行渐变填充 fill = stat(x)))+ # 沿x轴绘制具有填充梯度的山脊线和山脊线图 geom_density_ridges_gradient( # 缩放因子,用于相对于脊线之间的间距缩放脊线的高度。值为1表示,假设基线之间的间距均匀,则任何脊线的最高点都将碰到上方的基线。 scale=3, # 高度低于此临界值的线将被删除,即剪掉拖尾。 # 截断值是相对于整体最大值测量的,因此rel_min_height=0.01将删除所有1 \ 棱线。 # 默认值为0,因此不会删除任何内容。 rel_min_height=0.01, # 梯度线宽 gradient_lwd =.6)+ # 为两个轴删除不需要的填充 scale_x_continuous(expand = c(0.01, 0))+ # 通常必须设置“expand”选项 scale_y_discrete(expand = c(0.01,0))+ # 使用的X进行渐变填充 # 改变 option 可以使用不同的颜色 scale_fill_viridis(name="颜色棒名字", option = "D")+ labs( title="标题", subtitle="副标题")+ # 山脊线图的主题设置 (字体大小,网格线) theme_ridges(font_size = 13, grid = TRUE) +theme(axis.title.y = element_blank())# 去掉y轴标签 |
更改 option
1 | scale_fill_viridis(name="颜色棒名字", option = "A") |
1 | scale_fill_viridis(name="颜色棒名字", option = "E") |
分位数线和按分位数或概率着色
使用
1 2 | ggplot(iris, aes(x = Sepal.Length, y = Species)) + stat_density_ridges(quantile_lines = TRUE) |
或者
1 2 | ggplot(iris, aes(x = Sepal.Length, y = Species)) + stat_density_ridges(quantile_lines = TRUE,scale = 0.9) |
仅需修改
注:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | ggplot(iris, # 美学映射 x轴 y轴 渐变 aes( x=`Sepal.Length`, y=`Species`, # 使用x进行渐变填充 fill = stat(x)))+ # 沿x轴绘制具有填充梯度的山脊线和山脊线图 geom_density_ridges_gradient( # 缩放因子 scale=1, # 高度低于此临界值的线将被删除。 rel_min_height=0.01, # 梯度线宽 gradient_lwd =.6, quantile_lines = TRUE)+ scale_fill_viridis(name="Sepal.Length", option = "C") |
指定分位数,如只要中位数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | ggplot(iris, # 美学映射 x轴 y轴 渐变 aes( x=`Sepal.Length`, y=`Species`, # 使用x进行渐变填充 fill = stat(x)))+ # 沿x轴绘制具有填充梯度的山脊线和山脊线图 geom_density_ridges_gradient( # 缩放因子 scale=1, # 高度低于此临界值的线将被删除。 rel_min_height=0.01, # 梯度线宽 gradient_lwd =.6, quantile_lines = TRUE, quantiles = 2)+ scale_fill_viridis(name="Sepal.Length", option = "D") |
还可以通过切点而不是数字来指定分位数。例如,可以指出2.5%和97.5%的尾巴。
1 2 | ggplot(iris, aes(x = Sepal.Length, y = Species)) + stat_density_ridges(quantile_lines = TRUE, quantiles = c(0.025, 0.975), alpha = 0.7) |
通过分位数进行着色
1 2 3 4 5 6 | ggplot(iris, aes(x=Sepal.Length, y=Species, fill = factor(stat(quantile)))) + stat_density_ridges( geom = "density_ridges_gradient", calc_ecdf = TRUE, quantiles = 4, quantile_lines = TRUE ) + scale_fill_viridis_d(name = "Quartiles",option = "E") |
下四分位、上四分位
1 2 3 4 5 6 | ggplot(iris, aes(x=Sepal.Length, y=Species, fill = factor(stat(quantile)))) + stat_density_ridges( geom = "density_ridges_gradient", calc_ecdf = TRUE, quantiles = c(0.25, 0.75), quantile_lines = TRUE ) + scale_fill_viridis_d(name = "Quartiles",option = "F") |
1 2 3 4 5 6 7 8 9 10 | ggplot(iris, aes(x = Sepal.Length, y = Species, fill = factor(stat(quantile)))) + stat_density_ridges( geom = "density_ridges_gradient", calc_ecdf = TRUE, quantiles = c(0.025, 0.975) ) + scale_fill_manual( name = "Probability", values = c("#FF0000A0", "#A0A0A0A0", "#0000FFA0"), labels = c("(0, 0.025]", "(0.025, 0.975]", "(0.975, 1]") ) |
最后,当时
1 2 3 | ggplot(iris, aes(x = Sepal.Length, y = Species, fill = 0.5 - abs(0.5 - stat(ecdf)))) + stat_density_ridges(geom = "density_ridges_gradient", calc_ecdf = TRUE) + scale_fill_viridis_c(name = "Tail probability", direction = -1,option = "C") |
1 | option = "A" |
最后,关于颜色
参考:R语言的颜色应用
颜色数据集RColorBrewer
1 2 | library(RColorBrewer) brewer.pal.info |
使用:
brewer.pal(n, name),n为要生成多少个颜色,name对应上面图片中颜色条的名字
比如:
自定义渐变色板 colorRampPalette()
用法:
1.输入调色板的主要颜色,返回函数
2.在函数中输入想要获取的颜色数量,返回颜色数值
1 2 3 4 | library(scales) #调用scales库中的show_col函数 mypalette<- colorRampPalette(c("#FF66CC" , "#FF6600")) mycolors<- mypalette(12)#12种颜色,返回颜色数值 show_col(mycolors) |
1 2 3 | mypalette<- colorRampPalette(c("#FF66CC" , "#FF6600",'#66CCFF')) mycolors<- mypalette(16)#16种颜色,返回颜色数值 show_col(mycolors) |
在这里,可以使用
1 2 3 4 5 6 7 8 | ggplot(lincoln_weather, aes(x = `Mean Temperature [F]`, y = `Month`, fill = ..density..)) + # ..density.. 指按照计算出来的density填充颜色 geom_density_ridges_gradient( scale =3, rel_min_height = 0.00,#不剪尾 size = 0.3) + # 填充梯度 scale_fill_gradientn(colours = colorRampPalette(rev(brewer.pal(5,'GnBu')))(24))#通过5中颜色,产生24种渐变颜色 |
1 2 3 4 5 6 7 8 | ggplot(lincoln_weather, aes(x = `Mean Temperature [F]`, y = `Month`, fill = ..density..)) + # ..density.. 指按照计算出来的density填充颜色 geom_density_ridges_gradient( scale =3, rel_min_height = 0.00,#不剪尾 size = 0.3,quantile_lines = TRUE, quantiles = 2) + # 填充梯度 scale_fill_gradientn(colours = colorRampPalette(rev(brewer.pal(5,'Greys')))(24))#通过5中颜色,产生24种渐变颜色 |
用fill = stat(x)是一样的
最后,参考大佬做的图
https://evvail.com/2020/05/26/557.html
ggarrange解决多图排版问题
R成精系列-一页多图
需要安装R包ggpubr(版本> = 0.1.3),以轻松创建基于ggplot2的发布就绪图。
关于安装,我使用的时候遇到安装麻烦,可以采取手动安装,手动安装包教程
下载包地址
https://cran.r-project.org/web/packages/available_packages_by_name.html
代码运行结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | #加载包 library(ggplot2) library(ggridges) library(tidyverse) library(gridExtra) library(ggpubr) # 根据Sepal.Length绘制山峦图 p1 <- ggplot(iris) + geom_density_ridges_gradient(aes(x = `Sepal.Length`, y = `Species`, fill = ..x..), scale = 3, rel_min_height = 0.01, gradient_lwd = 0.1) + scale_x_continuous(expand = c(0.01, 0)) + scale_y_discrete(expand = c(0.01, 0)) + scale_fill_viridis(name = "Value", option = "C") + # 标题设置 labs(title = "Sepal.Length") + # 主题设置 theme_ridges(font_size = 13, grid = T) + theme(axis.title.y = element_blank()) p2 <- ggplot(iris) + geom_density_ridges_gradient(aes(x = `Sepal.Width`, y = `Species`, fill = ..x..), scale = 3, rel_min_height = 0.01, show.legend = T, gradient_lwd = 0.1) + scale_x_continuous(expand = c(0.01, 0)) + scale_y_discrete(expand = c(0.01, 0)) + scale_fill_viridis(name = "Value", option = "C") + labs(title = "Sepal.Width") + theme_ridges(font_size = 13, grid = FALSE) + theme(axis.title.y = element_blank()) p3 <- ggplot(iris) + geom_density_ridges_gradient(aes(x = `Petal.Length`, y = `Species`, fill = ..x..), scale = 3, rel_min_height = 0.01, gradient_lwd = 0.1) + scale_x_continuous(expand = c(0.01, 0)) + scale_y_discrete(expand = c(0.01, 0)) + scale_fill_viridis(name = "Value", option = "C") + labs(title = "Petal.Length") + theme_ridges(font_size = 13, grid = FALSE) + theme(axis.title.y = element_blank()) p4 <- ggplot(iris) + geom_density_ridges_gradient(aes(x = `Petal.Width`, y = `Species`, fill = ..x..), scale = 3, rel_min_height = 0.01, gradient_lwd = 0.1) + scale_x_continuous(expand = c(0.01, 0)) + scale_y_discrete(expand = c(0.01, 0)) + scale_fill_viridis(name = "Value", option = "C") + labs(title = "Petal.Width") + theme_ridges(font_size = 13, grid = FALSE) + theme(axis.title.y = element_blank()) # 组合各个图片 ggarrange( p1, p2, p3, p4, ncol = 2, nrow = 2, common.legend = TRUE, # legend共用 legend = "right" # 右侧显示legend ) |