关联数据大致可以分为以下几个图形来表示
- 散点图(两变量,多变量)
- 抖动图
- 计数图
- 气泡图
- 边际直方图/箱线图
数据前处理
R数据
library(ggplot2)
library(plotrix)
library(ggExtra)
## 全局主题设置
options(scipen=999) # 关掉像 1e+48 这样的科学符号
# 颜色设置(灰色系列)
cbp1 <- c("#999999", "#E69F00", "#56B4E9", "#009E73",
"#F0E442", "#0072B2", "#D55E00", "#CC79A7")
# 颜色设置(黑色系列)
cbp2 <- c("#000000", "#E69F00", "#56B4E9", "#009E73",
"#F0E442", "#0072B2", "#D55E00", "#CC79A7")
ggplot <- function(...) ggplot2::ggplot(...) +
scale_color_manual(values = cbp1) +
scale_fill_manual(values = cbp1) + # 注意: 使用连续色阶时需要重写
theme_bw()
python数据
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
#warnings.filterwarnings(action='once')
# 主题设置
plt.style.use('seaborn-whitegrid')
sns.set_style("whitegrid")
#print(mpl.__version__)# 3.5.1
#print(sns.__version__)# 0.12.0
散点图
该图展示两个变量间的关系。
- R
data("midwest", package = "ggplot2") #加载数据集
ggplot(midwest, aes(x=area, y=poptotal)) +
geom_point(aes(col=state, size=popdensity)) +
geom_smooth(method="loess", se=F) +
xlim(c(0, 0.1)) +
ylim(c(0, 500000)) +
labs(subtitle="Area Vs Population",
y="Population",
x="Area",
title="Scatterplot",
caption = "Source: midwest")
- python
midwest = pd.read_csv("/Volumes/Flower0501/研究学习目录/图形及其代码/data/midwest.csv")
sns.set(style="ticks",font_scale=1.5)#设置绘图风格
ax = sns.relplot(x="area",y="poptotal",data=midwest,
height=7,
hue='state',#添加分类变量
#**dict(s=20),#传入词典,调用Matplotlib中的参数,
size='popdensity',
legend='brief',#图例设置,"brief","full"
#col="state",#设置分面的行坐标
#row="popdensity" # 设置分面的纵坐标
)
ax.set_axis_labels("Area","Population").set(xlim=(0,0.1),ylim=(0, 500000))
plt.text(x=0.045, y=520000, s='Scatterplot', fontsize=16, weight='bold')
plt.text(x=0.045, y=500050, s='Area Vs Population', fontsize=10, alpha=0.75)
plt.show()
python的散点图只能对每一个分组添加趋势线,而没有办法对总的添加(至少目前我办不到)
sns.set(style="ticks",font_scale=1.5)#设置绘图风格
ax = sns.lmplot(x="area",y="poptotal",data=midwest,
height=7,
hue='state',#添加分类变量
#**dict(s=20),#传入词典,调用Matplotlib中的参数,
legend='brief',#图例设置,"brief","full"
#col="state",#设置分面的行坐标
#row="popdensity" # 设置分面的纵坐标
ci=None,# 置信区间显示范围
)
ax.set_axis_labels("Area","Population").set(xlim=(0,0.1),ylim=(0, 500000))
plt.text(x=0.045, y=520000, s='Scatterplot', fontsize=16, weight='bold')
plt.text(x=0.045, y=500050, s='Area Vs Population', fontsize=10, alpha=0.75)
plt.show()
抖动图
多个点具有完全相同的X和Y值, 为避免多个点相互绘制并隐藏,可稍微抖动点,以便直观地看到它们。
- R
ggplot(mpg, aes(cty, hwy))+
geom_jitter(width = .5, size=1) +
labs(subtitle="mpg: city vs highway mileage",
y="hwy",
x="cty",
title="Jittered Points")
- python
mpg = pd.read_csv("./datasets/mpg_ggplot2.csv")
fig, ax = plt.subplots(figsize=(10, 6), dpi=80)
sns.stripplot(x=mpg.cty,
y=mpg.hwy,
jitter=0.25,
size=8,
ax=ax,
linewidth=.5,
palette='Set1')
sns.set(style="whitegrid", font_scale=1.1)
plt.title('Use jittered plots to avoid overlapping of points')
plt.show()
计数图
区别于抖动图,多个点相互绘制并隐藏时,可使用点的大小区分重叠的程度,点的大小越大,周围的点的集中度就越大,重叠的越多。
- R
ggplot(mpg, aes(cty, hwy))+
geom_count(col="tomato3", show.legend=F) +
labs(subtitle="mpg: city vs highway mileage",
y="hwy",
x="cty",
title="Counts Plot")
- python
PS:也不知道为什么,把size改成sizes就可以运行了,否则就要报错:
s must be a scalar, or float array-like with the same size as x and y
mpg = pd.read_csv("/Volumes/Flower0501/研究学习目录/图形及其代码/data/mpg_ggplot.csv")
df_counts = mpg.groupby(['hwy', 'cty']).size().reset_index(name='counts')
# Draw Stripplot
fig, ax = plt.subplots(figsize=(10, 6), dpi=80)
sns.stripplot(x=df_counts.cty,
y=df_counts.hwy,
sizes=df_counts.counts * 20,
ax=ax,
palette='Set1')
# Decorations
sns.set(style="whitegrid", font_scale=1.1)
plt.title('Counts Plot - Size of circle is bigger as more points overlap')
plt.show()
边际直方图/箱线图
如果您想在同一个图中显示变量的关系和分布,可以使用边际直方图。
边际直方图
- R
library(ggExtra)
mpg_select <- mpg[mpg$hwy >= 35 & mpg$cty > 27, ]
g <- ggplot(mpg, aes(cty, hwy)) +
geom_count() +
geom_smooth(method="lm", se=F)
ggMarginal(g, type = "histogram", fill="transparent")
- python-matplotlib
mpg = pd.read_csv("/Volumes/Flower0501/研究学习目录/图形及其代码/data/mpg_ggplot.csv")
fig = plt.figure(figsize=(10, 6), dpi=100)
grid = plt.GridSpec(4, 4, hspace=0.5, wspace=0.2)
ax_main = fig.add_subplot(grid[:-1, :-1])
ax_right = fig.add_subplot(grid[:-1, -1], xticklabels=[], yticklabels=[])
ax_bottom = fig.add_subplot(grid[-1, 0:-1], xticklabels=[], yticklabels=[])
## 散点主图
ax_main.scatter('cty',
'hwy',
s=mpg.cty * 4,
c=mpg.manufacturer.astype('category').cat.codes,
alpha=.9,
data=mpg,
cmap="Set1",
edgecolors='gray',
linewidths=.5)
## 底部直方图
ax_bottom.hist(mpg.cty,
40,
histtype='stepfilled',
orientation='vertical',
color='#098154')
ax_bottom.invert_yaxis()
## 左侧直方图
ax_right.hist(mpg.hwy,
40,
histtype='stepfilled',
orientation='horizontal',
color='#098154')
# 修饰图形
ax_main.set(title='Scatterplot with Histograms \n cty vs hwy',
xlabel='cty',
ylabel='hwy')
ax_main.title.set_fontsize(10)
for item in ([ax_main.xaxis.label, ax_main.yaxis.label] +
ax_main.get_xticklabels() + ax_main.get_yticklabels()):
item.set_fontsize(10)
xlabels = ax_main.get_xticks().tolist()
ax_main.set_xticklabels(xlabels)
plt.show()
- python-seaborn
mpg = pd.read_csv("/Volumes/Flower0501/研究学习目录/图形及其代码/data/mpg_ggplot.csv")
sns.set(style="whitegrid", font_scale=1.5) #设置主题,文本大小
g = sns.jointplot(
x='cty',
y='hwy',
data=mpg, #输入两个绘图变量
color='#098154', #修改颜色
)
g.fig.set_size_inches(10, 8) #设置图尺寸
边际箱线图
- R
g <- ggplot(mpg, aes(cty, hwy)) +
geom_count() +
geom_smooth(method="lm", se=F)+
labs(title = "Scatterplot with boxplot",subtitle = "cty vs hwy",x="cty",y="hwy")
ggMarginal(g, type = "boxplot", fill="transparent")
- python
mpg = pd.read_csv("/Volumes/Flower0501/研究学习目录/图形及其代码/data/mpg_ggplot.csv")
# 创建绘图区域并设置王哥
fig = plt.figure(figsize=(10, 8), dpi=100)
grid = plt.GridSpec(
4, 4, hspace=0.5, wspace=0.2
)
# 定义坐标轴
ax_main = fig.add_subplot(grid[:-1, :-1])
ax_right = fig.add_subplot(grid[:-1, -1], xticklabels=[], yticklabels=[])
ax_bottom = fig.add_subplot(grid[-1, 0:-1], xticklabels=[], yticklabels=[])
# 主图散点图
ax_main.scatter(x='cty',
y='hwy',
s=mpg.cty * 5,
c=mpg.manufacturer.astype('category').cat.codes,
alpha=.9,
data=df,
cmap="Set1",
edgecolors='black',
linewidths=.5)
# 为每个轴添加轴线图
sns.boxplot(mpg.hwy, ax=ax_right, orient="v", linewidth=1, palette='Set1')
sns.boxplot(mpg.cty, ax=ax_bottom, orient="h", linewidth=1, palette='Set1')
# 修饰主图
# 移除x/y轴坐标轴
ax_bottom.set(xlabel='')
ax_right.set(ylabel='')
# 设置标题与坐标轴
ax_main.set(title='Scatterplot with Histograms \n cty vs hwy',
xlabel='cty',
ylabel='hwy')
# 设置主题参数
ax_main.title.set_fontsize(12)
for item in ([ax_main.xaxis.label, ax_main.yaxis.label] +
ax_main.get_xticklabels() + ax_main.get_yticklabels()):
item.set_fontsize(11)
plt.show()