前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据可视化 | 双Y轴可视化绘制方法(Python、R两种方法)

数据可视化 | 双Y轴可视化绘制方法(Python、R两种方法)

作者头像
郭好奇同学
发布2020-12-28 10:55:27
1.6K0
发布2020-12-28 10:55:27
举报
文章被收录于专栏:好奇心Log好奇心Log

最近有很多小伙伴私信我关于双Y轴图的绘制方法? 这里给出Python-matplotlib绘制方法和R-ggplot2的绘制方法

Python语言

这里我们直接就给出数据预览和可视化设计的代码,图中部分代码我们再做详细解释,数据预览如下:

自定义的颜色字典year_color构造代码如下:

代码语言:javascript
复制
color = ("#51C1C8", "#E96279", "#44A2D6", "#536D84",
         "#51C1C8", "#E96279", "#44A2D6", "#536D84")
year = artist_01.index.to_list()
year_color = dict(zip(year,color))
year_color

可视化代码如下:

代码语言:javascript
复制
plt.style.use('fivethirtyeight')
fig,ax = plt.subplots(figsize=(8,4),dpi=200,facecolor='white',edgecolor='white')
ax.set_facecolor('white')

x = np.arange(0,len(artist_01),1)
y = artist_01['data01'].values

#绘制连接点的线
line = ax.plot(x,y,color='#333333',lw=1.,zorder=2)
#绘制不同散点图
scatter_out = ax.scatter(x,y,s=500,zorder=1,color='white',ec='grey',alpha=.7,lw=.5)
for i in artist_01.index.to_list():
    scatter = ax.scatter(x[i],y[i],s=180,zorder=3,ec='k',lw=.4,color=year_color[i])
scatter_in = ax.scatter(x,y,s=30,zorder=3,color="#333333")

#定制化绘制(设置图表风格)
ax.grid(color='gray',lw=.5,alpha=.5) #设置网格
ax.tick_params(left=False,bottom=False,labelbottom=False,labelsize=10,colors='gray')#设置刻度
ax.set_ylim(bottom=-3,top=43)#设置轴范围
ax.set_yticks(np.arange(0, 45, step=5)) #设置刻度标签
ax.set_xticks(np.arange(-.5, 8, step=.5))
#添加横线(修饰)
ax.axhline(y=0,color='#45627C',lw=3)
#添加数字标签
label_text = {"size":13,"color":"k",'weight':'semibold'}
for a,b in zip(x,y):
    ax.text(a, b+2.5, '%.0f' % b, ha='center', va= 'bottom',fontdict=label_text,color=year_color[a])
#设置轴脊(spine)
for spine in ['top','bottom','left','right']:
    ax.spines[spine].set_color("#FFFFFF") #设置颜色/set_visible()设置显示与否
for i in artist_01.index.to_list()[:3]:
    axins.scatter(x[i],y[i],s=80,color=year_color[i],zorder=2)
    
#添加标题处小图
#添加小散点图:重点掌握   
axins = inset_axes(ax, width=.4, height=.4,loc='upper left',
                   bbox_to_anchor=(0.01, 0.22, 1, 1),
                   bbox_transform=ax.transAxes,
                   borderpad=0)
axins.set_ylim(bottom=8,top=35)
axins.set_xlim(left=-.5,right=2.5)
axins.plot(x[:3],y[:3],color='#333333',lw=1.,zorder=1)
for i in artist_01.index.to_list()[:3]:
    axins.scatter(x[i],y[i],s=80,color=year_color[i],zorder=2)
axins.axis('off')
#绘制小横线:原理同上
line = inset_axes(ax,width=5.3, height=.4,loc='upper left',
                  bbox_to_anchor=(-0.015, 0.15, 1, 1),
                  bbox_transform=ax.transAxes,
                  borderpad=0)
line.plot([.1,.7],[.1,.1],color='#45627C',lw=2)
line.axis('off')

#添加阴影效果
for i in artist_01.index.to_list():
    ax.axvspan(i-.35, i+.35, facecolor='gray',alpha=.1,zorder=0)
    
#添加双y轴:使用Axes.twinx()方法绘制
second_plot = ax.twinx()
second_plot.set_ylim(bottom=-3,top=43)
second_plot.set_yticks(np.arange(0, 50, step=10))
second_plot.set_xticks(np.arange(-.5, 8, step=.5))
second_plot.tick_params(left=False,bottom=False,labelbottom=False,labelsize=10,colors='k')
second_plot.grid(color="none",zorder=0)
second_plot.set_axisbelow(True)
for spine in ['top','bottom','left','right']:
    second_plot.spines[spine].set_visible(False) #("#FFFFFF")

y2 = artist_01['data02'].values
label_text = {"size":28,"color":"white",'weight':'light'}
for x,y2 in zip(np.arange(len(artist_01)).tolist(),artist_01['data02'].to_list()):
    second_plot.plot([x,x],[0,y2],lw=20,color=color[x],solid_capstyle='round')
    #绘制空心圆
    second_plot.scatter(x,0,s=150,c='white',zorder=3)
    second_plot.scatter(x,0,s=60,c=color[x],zorder=4)
    second_plot.scatter(x,0,s=15,c='white',zorder=5)
   
# 添加文本信息
label_font = {"size":15,'weight':'bold'}
for i,x,text in zip(artist_01.index.to_list(),np.arange(0,len(artist_01),1),artist_01['year'].values):
    ax.text(x, -8,text ,ha='center', va= 'bottom',fontdict=label_font,color=year_color[i],zorder=2)

ax.text(.39,1.2,'\nSecond Y Axes Plot Exercise',transform = ax.transAxes,
        ha='center', va='center',fontsize = 20,color='k',fontweight="bold")
ax.text(.02,1.04,'Use the Matplotlib axes.Axes.twinx()',
        transform = ax.transAxes,
        ha='left', va='center',fontsize = 9,color='#45627C')

ax.text(.91,.02,'\nVisualization by DataCharm',transform = ax.transAxes,
        ha='center', va='center',fontsize = 7,color='black')
plt.savefig(r'double_y_axis_plot.png',width=6,height=3,
            dpi=900,bbox_inches='tight',facecolor='white')
#ax.set_axisbelow(True)
plt.show()

解释:

1. 添加横线(修饰)

代码语言:javascript
复制
ax.axhline(y=0,color='#45627C',lw=3)

2. 添加标题处小图

代码语言:javascript
复制
axins = inset_axes(ax, width=.4, height=.4,loc='upper left',
                   bbox_to_anchor=(0.01, 0.22, 1, 1),
                   bbox_transform=ax.transAxes,
                   borderpad=0)
axins.set_ylim(bottom=8,top=35)
axins.set_xlim(left=-.5,right=2.5)
axins.plot(x[:3],y[:3],color='#333333',lw=1.,zorder=1)
for i in artist_01.index.to_list()[:3]:
    axins.scatter(x[i],y[i],s=80,color=year_color[i],zorder=2)
axins.axis('off')

3. 添加双y轴:使用Axes.twinx()方法绘制:重点

代码语言:javascript
复制
#添加双y轴:使用Axes.twinx()方法绘制
second_plot = ax.twinx()
second_plot.set_ylim(bottom=-3,top=43)
second_plot.set_yticks(np.arange(0, 50, step=10))
second_plot.set_xticks(np.arange(-.5, 8, step=.5))
second_plot.tick_params(left=False,bottom=False,labelbottom=False,labelsize=10,colors='k')
second_plot.grid(color="none",zorder=0)
second_plot.set_axisbelow(True)
for spine in ['top','bottom','left','right']:
    second_plot.spines[spine].set_visible(False) #("#FFFFFF")

y2 = artist_01['data02'].values
label_text = {"size":28,"color":"white",'weight':'light'}
for x,y2 in zip(np.arange(len(artist_01)).tolist(),artist_01['data02'].to_list()):
    second_plot.plot([x,x],[0,y2],lw=20,color=color[x],solid_capstyle='round')
    #绘制空心圆
    second_plot.scatter(x,0,s=150,c='white',zorder=3)
    second_plot.scatter(x,0,s=60,c=color[x],zorder=4)
    second_plot.scatter(x,0,s=15,c='white',zorder=5)

最终的可视化结果如下:

总结:Python-matplotlib 绘制双Y轴的关键就是使用Axes.twinx()方法再次添加一个绘图对象,再把要绘制的对象在此绘图对象上绘制即可,其他和正常的matplotlib语法一样。

R语言

在介绍完Python-matplotlib 绘制双Y轴后,我们再次介绍R-ggplot2如何绘制双Y轴,由于绘制上面的可视化结果较为繁琐,这里我们直接生成样例数据进行双Y轴的讲解。主要涉及的知识点就是scale_y_continuous() 或scale_x_continuous()中的sec.axis()属性设置。

构建数据

这里我们构建虚拟数据,代码如下:

代码语言:javascript
复制
data <- data.frame(
  day = as.Date("2019-01-01") + 0:99,
  temperature = runif(100) + seq(1,100)^2.5 / 10000,
  price = runif(100) + seq(100,1)^1.5 / 10
)
head(data)

数据预览如下(部分):

可视化绘制

这里我们直接给出代码,大家不懂的可以参考ggplot2官网,代码如下:

代码语言:javascript
复制
coeff <- 10
temperatureColor <- "#75B8D1"
priceColor <- "#D175B8"

double_y <-ggplot(data, aes(x=day)) +
 geom_line(aes(y=temperature), size=1.5, color=temperatureColor) + 
 geom_line(aes(y=price / coeff), size=1.5, color=priceColor) +
 #设置双轴关键代码
 scale_y_continuous(
   # first axis name
   name = "Temperature (C°)",
   # 定制化设置第二个图例属性
   sec.axis = sec_axis(trans = ~.*coeff, name="Price ($)")
 ) + 
 labs(x="",
      title = "R Charts Exercise: <span style='color:#D20F26'>Double Y Axis</span>",
      subtitle = "processed charts with <span style='color:#1A73E8'>scale_y/x_continuous:sec_axis()</span>",
      caption = "Visualization by <span style='color:#DD6449'>DataCharm</span>") +
 theme_ft_rc()+
 theme(
   axis.title.y = element_text(color = temperatureColor, size=13),
   axis.title.y.right = element_text(color = priceColor, size=13),
   plot.title = element_markdown(hjust = 0.5,vjust = .5,color = "black",
                                 size = 20, margin = margin(t = 1, b = 12)),
   plot.subtitle = element_markdown(hjust = 0,vjust = .5,size=15),
   plot.caption = element_markdown(face = 'bold',size = 12),
 ) 

设置双轴代码:

代码语言:javascript
复制
 #设置双轴关键代码
 scale_y_continuous(
   # first axis name
   name = "Temperature (C°)",
   # 定制化设置第二个图例属性
   sec.axis = sec_axis(trans = ~.*coeff, name="Price ($)")
 ) + 

最终可视化代码如下:

总结

本期推文我们简单介绍了Python-matplotlib和R-ggplot2 绘制双Y轴的绘制方法,希望可以帮助到有需要的小伙伴。我们基础系列的图表绘制教程还在继续中哦,感谢大家持续支持和关注。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-12-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 好奇心Log 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Python语言
  • R语言
    • 构建数据
      • 可视化绘制
      • 总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档