魔都上海4日旅游攻略?Python动态图告诉你!

点击上方“Python爬虫与数据挖掘”,进行关注

回复“书籍”即可获赠Python从入门到进阶共10本电子书

博学而约取,厚积而薄发。

开场段子 

【野人献曝】战国时期,宋国有一个没有见过世面的农夫,由于家贫,终日穿一件粗麻衣,勉强过冬。第二年春天,天气晴朗,他就脱光衣服在太阳下曝晒,觉得十分舒服。由于没有见过漂亮的皮衣和高大的房子,就对妻子说将把这取暖的办法进献给国王。

【成语释义】比喻贡献的不是什么珍贵的东西,常用于向人建议时候的客套话。

魔都魔在哪里

人们通常戏称上海为魔都。那么上海魔在哪里呢?这里的魔主要有两层含义。第一是魔力,第二是魔幻。

先说魔力。上海是我国的金融中心,是我国经济总量第一的城市,是我国人均收入最高的城市,是我国进出口贸易第一的城市,也是我国最开放的城市之一。拼多多、B站、携程、饿了么等知名互联网公司的总部都在上海,腾讯、阿里、美团、头条等在上海都有办公部门。加之上海相比北京宽松的户籍政策,每年吸引着无数打工人来上海追寻梦想。浪奔,浪流,万里滔滔江水永不休。

再说魔幻。上海是一座奇迹之城,从1843年作为通商口岸开放到如今不过170余年,上海从一个名不见经传的小村落一跃成为中国第一亚洲第二大城市,发展速度可谓奇迹。上海也是一座混沌之城,这里有见证800年暮鼓晨钟的静安寺,近600年历史的城隍庙,历经450余年风雨的豫园,也有外滩的“万国建筑群”,“十里洋场”盛况空前,东方明珠夺目璀璨,亚洲第一高楼高达632米的上海中心大厦。可谓亦中亦西,亦今亦古。

上海旅游攻略

上海知名度最高的旅游景点,应该是上海外滩,东方明珠电视塔,以及迪士尼乐园。

此外,豫园、南京路、人民广场、静安寺、新天地、陆家嘴、崇明岛、朱家角、滴水湖、淀山湖、枫泾古镇 等景点也是值得一去的好地方。

这么多的景点?该如何规划呢?下面这份上海4日旅游攻略,或许可以帮助到你。

先上数据

Day1 上海城隍庙旅游区(2小时) → 豫园(1小时) → 南京路步行街(3小时) → 外滩(1小时) 

Day2 中华艺术宫(4小时) → 田子坊(2小时) → 上海新天地(2小时) 

Day3 上海迪士尼度假区(1天) 

Day4 上海杜莎夫人蜡像馆(3小时) → 陆家嘴(2小时) → 东方明珠广播电视塔(2小时)

再上视频

最后上代码

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, (255, 255, 255))
    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 trace_map_dance(df,title = "上海经典4日旅行路线",
                     filename = None,
                     figsize = (8,6),dpi = 144,
                     duration = 0.5,
                     anotate_points = ["外滩","上海迪士尼度假区","陆家嘴"]):

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

    def plot_frame(i):

            ax.clear()
            ax.axis("off")
            
            k = i//3+1
            m = i%3

            dfdata = df.iloc[:k,:].copy()
            dftmp = df.iloc[:k-1,:].copy()
            text = dfdata["day"].tolist()[-1]
            
            #============================================================
            #绘制背景
            #============================================================
            
            #设置绘图范围
            bounds = dfcity.total_bounds # k==1   
            if 1<k<len(df)+1:
                bounds = dfplace.query("day=='{}'".format(text)).total_bounds
            if k>=len(df)+1:
                bounds = dfplace.total_bounds
                
            (xmin,ymin,xmax,ymax) = bounds
            cx = (xmin+xmax)/2.0
            cy = (ymin+ymax)/2.0
            dx = max(xmax-xmin,100)
            dy = max(ymax-ymin,100)

            if dx/dy<8/6.0:
                dx = dy*8/6.0
            else:
                dy = dx*6.0/8
            bounds = np.array([min(cx-8000,cx-dx/2.0),min(cy-6000,cy-dy/2.0),
               max(cx+8000,cx+dx/2.0),max(cy+6000,cy+dy/2.0)])
                
            ax.set_xlim(bounds[0]-(bounds[2]-bounds[0])/3, bounds[2]+(bounds[2]-bounds[0])/3)    
            ax.set_ylim(bounds[1]-(bounds[3]-bounds[1])/3, bounds[3]+(bounds[3]-bounds[1])/3)
                
            gaode = 'http://wprd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7'
            openstreet = "https://{s}.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png"
            ctx.add_basemap(ax,source=gaode,alpha=0.5)
            
            #============================================================
            #绘制散点
            #============================================================

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

                # 添加注释文字
                for j,p in enumerate(dftmp.index):
                    px,py,pz = dftmp.loc[p,["x","y","z"]].tolist() 
                    if p in anotate_points:
                        ax.annotate(p,xy = (px,py),  xycoords = "data",xytext = (-20,15),
                        fontsize = 10,fontweight = "bold",color = cmap[j], textcoords = "offset points")
                        
            #绘制轨迹线
            lines = [dfdata[["x","y"]].values[i:i+2] for i in range(len(dfdata)-1)] 
            for ln in lines[:-1]:
                x, y = np.transpose(ln)
                line = plt.Line2D(x,y,color="gray",linestyle="-",linewidth= 2.5)
                ax.add_artist(line)
            
            # 添加标题和排名序号
            ax.set_title(title,color = "black",fontsize = 12)
            ax.text(0.13, 0.9, text, va="center", ha="center", 
                         alpha=0.5, size = 50,transform = ax.transAxes)
            
            # 结尾呈现全局轨迹无动画
            if i>=3*len(df):
                for ln in lines[-1:]:
                    x, y = np.transpose(ln)
                    line = plt.Line2D(x,y,color="gray",linestyle="-",linewidth= 2.5)
                    ax.add_artist(line)
                return 0

            # 添加注意力动画
            if m==0:
                px,py,pz = dfdata["x"][[-1]],dfdata["y"][[-1]],dfdata["z"][-1]
                p = dfdata.index[-1]+":"+str(pz)+"Hours"
                ax.scatter(px,py,s = 800*pz/df["z"].mean(),
                   c = cmap[len(dfdata)-1:len(dfdata)],alpha = 0.5,zorder = 4)
                ax.annotate(p,xy = (px,py),  xycoords = "data",
                        xytext = (-20,15),fontsize = 20,fontweight = "bold",
                        color = cmap[k-1], textcoords = "offset points",zorder = 5)
                
                for ln in lines[-1:]:
                    x, y = np.transpose(ln)
                    line = plt.Line2D(x,y,color="gray",linestyle=":",linewidth= 4.5)
                    ax.add_artist(line)
            
            if m==1:
                px,py,pz = dfdata["x"][[-1]],dfdata["y"][[-1]],dfdata["z"][-1]
                p = dfdata.index[-1]+":"+str(pz)+"Hours"
                ax.scatter(px,py,s = 400*pz/df["z"].mean(),
                   c = cmap[len(dfdata)-1:len(dfdata)],alpha = 0.5,zorder = 4)
                ax.annotate(p,xy = (px,py),  xycoords = "data",
                        xytext = (-20,15),fontsize = 15,fontweight = "bold",
                        color = cmap[k-1], textcoords = "offset points",zorder = 5)
                
                for ln in lines[-1:]:
                    x, y = np.transpose(ln)
                    line = plt.Line2D(x,y,color="gray",linestyle="--",linewidth= 3.5)
                    ax.add_artist(line)
                
            if m==2:
                px,py,pz = dfdata["x"][[-1]],dfdata["y"][[-1]],dfdata["z"][-1]
                p = dfdata.index[-1]+":"+str(pz)+"Hours"
                ax.scatter(px,py,s = 100*pz/df["z"].mean(),
                   c = cmap[len(dfdata)-1:len(dfdata)],alpha = 0.5,zorder = 4)
                ax.annotate(p,xy = (px,py),  xycoords = "data",
                        xytext = (-20,15),fontsize = 10,fontweight = "bold",
                        color = cmap[k-1], textcoords = "offset points",zorder = 5)
                
                for ln in lines[-1:]:
                    x, y = np.transpose(ln)
                    line = plt.Line2D(x,y,color="gray",linestyle="-",linewidth= 2.5)
                    ax.add_artist(line)
            return 0
                
    my_animation = animation.FuncAnimation(fig,plot_frame,
                            frames = range(0,3*len(df)+5),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 = "上海经典4日旅行路线.html"
trace_map_dance(df,filename=html_file)


收工 。

    Python进阶者最近搞了一个Python交流群,这个Python交流群已经300多人了,有需要加入该群的小伙伴可以加我好友,一起学习,共同进步。

------------------- End -------------------

往期精彩文章推荐:

欢迎大家点赞,留言,转发,转载,感谢大家的相伴与支持

想加入Python学习群请在后台回复【入群

万水千山总是情,点个【在看】行不行

/今日留言主题/

随便说一两句吧~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值