QS世界排名前200的大学都在哪里?Python动态图告诉你!

Python与算法之美

共 13570字,需浏览 28分钟

 ·

2021-08-11 09:59

今日表情 😋 :


世界上较为主流的大学排名有美国U.S. News世界大学排名、英国QS世界大学排名、英国泰晤士高等教育世界大学排名,以及学术类排名如世界大学自然指数排名、中国软科世界大学学术排名等。


我们选用的是6月份公布的2021年度英国QS世界大学排名。


QS通过如下6个指标对各大学进行评估:

  • 学术声誉(40%)

  • 雇主声誉(10%)

  • 师生比(20%)

  • 每名教师的引用率(20%)

  • 国际教师比例(5%)

  • 留学生比例(5%)


按照这个评估标准,中国共有14所大学排进前200名,分别是:

15 清华大学(中国)

22 香港大学(中国香港) 

23 北京大学(中国) 

27 香港科技大学(中国香港) 

34 复旦大学(中国) 

43 香港中文大学(中国香港) 

47 上海交通大学(中国) 

48 香港城市大学(中国香港) 

53 浙江大学(中国) 

67 台湾大学(中国台湾) 

75 香港理工大学(中国香港) 

94 中国科学技术大学(中国) 

126 南京大学(中国) 

168 国立清华大学(中国台湾)


那么,QS排名前200名的这些世界顶级大学都在哪里呢?我们用Python动态图来盘点一下吧!


先上图片


再上视频



最后上代码


import numpy as np 
import pandas as pd 
import geopandas as gpd 
import shapely 
from shapely import geometry as geo 
from shapely import wkt 
import geopandas as gpd 
import matplotlib.pyplot as plt 
import matplotlib.animation as  animation 
import contextily as ctx 

import imageio
import os 
from PIL import Image

plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['animation.writer'] = 'html'
plt.rcParams['animation.embed_limit'] = 100

def rgba_to_rgb(img_rgba):
    img_rgb = Image.new("RGB", img_rgba.size, (255255255))
    img_rgb.paste(img_rgba, mask=img_rgba.split()[3]) 
    return img_rgb 

def html_to_gif(html_file, gif_file, duration=0.5):
    path = html_file.replace(".html","_frames")
    images = [os.path.join(path,x) for x in sorted(os.listdir(path))]
    frames = [imageio.imread(x) for x in images]
    if frames[0].shape[-1]==4:
        frames = [np.array(rgba_to_rgb(Image.fromarray(x))) for x in frames]
    imageio.mimsave(gif_file, frames, 'gif', duration=duration)
    return gif_file

cmap = [
'#2E91E5',
'#1CA71C',
'#DA16FF',
'#B68100',
'#EB663B',
'#00A08B',
'#FC0080',
'#6C7C32',
'#862A16',
'#620042',
'#DA60CA',
'#0D2A63']*100

def getCoords(geom):
    if isinstance(geom,geo.MultiPolygon):
        return [np.array(g.exterior) for g in geom.geoms]
    elif isinstance(geom,geo.Polygon):
        return [np.array(geom.exterior)]
    elif isinstance(geom,geo.LineString):
        return [np.array(geom)]
    elif isinstance(geom,geo.MultiLineString):
        return [np.array(x) for x in list(geom.geoms)]
    else:
        raise Exception("geom must be one of [polygon,MultiPolygon,LineString,MultiLineString]!")

#底图数据
dfcoutries = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres')).set_crs("epsg:4326")

#散点数据
dfpoints = gpd.read_file("./data/QS世界大学排名前200.geojson")
df = pd.DataFrame({"x":[pt.x for pt in dfpoints["geometry"]],
                  "y": [pt.y for pt in dfpoints["geometry"]]})

df["z"] = 1.0
df.index = dfpoints["name"].values

def bubble_map_dance(df,title = "QS世界排名前200大学分布",
                     filename = None,
                     figsize = (8,6),dpi = 144,
                     duration = 0.5,
                     anotate_points = [])
:


    fig, ax_base =plt.subplots(figsize=figsize,dpi=dpi)

    def plot_frame(i):
        ax_base.clear()

        #============================================================
        #绘制底图
        #============================================================

        dfcoutries.plot(ax=ax_base,color='white',edgecolor='gray',alpha = 0.5

        #设置绘图范围
        ax_base.set_xlim(-198.0198.00000000000009)
        ax_base.set_ylim(-98.6822564999999892.3273865)
        ax_base.axis("off")


        #============================================================
        #绘制散点
        #============================================================

        k = i//3+1
        m = i%3
        text = "NO."+str(len(df)+1-k) 

        dfdata = df.iloc[:k,:].copy()
        dftmp = df.iloc[:k-1,:].copy()

        # 绘制散点图像
        if len(dftmp)>0:
            ax_base.scatter(dftmp["x"],dftmp["y"],s = 40*dftmp["z"]/df["z"].mean(),
                   c = (cmap*100)[0:len(dftmp)],alpha = 0.4,zorder = 3)

            # 添加注释文字
            for i,p in enumerate(dftmp.index):
                px,py,pz = dftmp.loc[p,["x","y","z"]].tolist() 
                if p in anotate_points:
                    ax_base.annotate(p,xy = (px,py),  xycoords = "data",xytext = (-15,10),
                    fontsize = 10,fontweight = "bold",color = cmap[i], textcoords = "offset points")

        # 添加标题和排名序号
        ax_base.set_title(title,color = "black",fontsize = 12)
        #ax_base.text(0.5, 0.95, title, va="center", ha="center", 
        #            size = 12,transform = ax_base.transAxes)
        ax_base.text(0.170.3, text, va="center", ha="center"
                     alpha=0.4, size = 40,transform = ax_base.transAxes)

        # 添加注意力动画
        if m==0:
            px,py,pz = dfdata["x"][[-1]],dfdata["y"][[-1]],dfdata["z"][-1]
            p = dfdata.index[-1]
            ax_base.scatter(px,py,s = 200*pz/df["z"].mean(),
               c = cmap[len(dfdata)-1:len(dfdata)],alpha = 0.4,zorder = 4)
            ax_base.annotate(p,xy = (px,py),  xycoords = "data",
                    xytext = (-15,10),fontsize = 15,fontweight = "bold",
                    color = cmap[k-1], textcoords = "offset points",zorder = 5)

        if m==1:
            px,py,pz = dfdata["x"][[-1]],dfdata["y"][[-1]],dfdata["z"][-1]
            p = dfdata.index[-1]
            ax_base.scatter(px,py,s = 100*pz/df["z"].mean(),
               c = cmap[len(dfdata)-1:len(dfdata)],alpha = 0.4,zorder = 4)
            ax_base.annotate(p,xy = (px,py),  xycoords = "data",
                    xytext = (-15,10),fontsize = 12,fontweight = "bold",
                    color = cmap[k-1], textcoords = "offset points",zorder = 5)

        if m==2:
            px,py,pz = dfdata["x"][[-1]],dfdata["y"][[-1]],dfdata["z"][-1]
            p = dfdata.index[-1]
            ax_base.scatter(px,py,s = 40*pz/df["z"].mean(),
               c = cmap[len(dfdata)-1:len(dfdata)],alpha = 0.4,zorder = 4)
            ax_base.annotate(p,xy = (px,py),  xycoords = "data",
                    xytext = (-15,10),fontsize = 9,fontweight = "bold",
                    color = cmap[k-1], textcoords = "offset points",zorder = 5)
                
    my_animation = animation.FuncAnimation(fig,plot_frame,frames = range(0,3*len(df)),interval = int(duration*1000))
    
    if filename is None:
        try:
            from IPython.display import HTML
            HTML(my_animation.to_jshtml())
            return HTML(my_animation.to_jshtml())
        except ImportError:
            pass
    else:
        my_animation.save(filename)
        return filename
    

html_file = "QS世界排名前200大学分布.html"
bubble_map_dance(df,filename = html_file)

gif_file = html_file.replace(".html",".gif")
html_to_gif(html_file,gif_file,duration=0.5)


收工。😋


万水千山总是情,点个在看行不行?😋

浏览 30
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报