精华内容
下载资源
问答
  • 在R中实现动态气泡图
    2021-03-21 09:57:48

    最近我逐渐发现了ggplot2这个包的好处——只要用过一次,就再也不想回头使用R中自带的作图函数了。前两天鼓捣完一个地图的数据,又受到统计之都文章的影响,我忽然想起了Hans Rosling在TED上的精彩演讲。在图中横坐标是国民收入,纵坐标是国民的期望寿命,气泡的大小则是该国人口。整个图从1800年的统计数据开始,一直到2009年不断动态地展示,图上的气泡也随着时间变化不停地抖动上升。有一位在斯坦福专做可视化的博士用JavaScript在网页上重现了这段动态效果图,点开页面即可观看:http://bost.ocks.org/mike/nations/。

    于是今天我便将这个图尝试着用R中的ggplot2与animation包实现了出来,边实现边研究ggplot2的用法,花了一天的时间做成了下面的这个视频。

    简单地说一下流程:首先是数据文件的获取。数据能够在github上找到,但是数据是JSON格式的,只有一行,因此我的大部分代码都在为让数据变成一个二维矩阵的形式而努力着……很多国家会出现某些年没有统计数据的情况,因此我用了线性插值填补。最后,有两个国家只有一年有数据,我只能将它们删掉了。

    弄好了数据就可以使用ggplot2画图了。为了让图像好看,我调整了图像的属性,比如圆圈的大小范围,学习加边框,学习图中加文字(annotate)等语法。但我现在感觉还是有一些地方能够微调改进。

    最后使用animation包中的saveMovie函数,结合ffmpeg导出成了一个视频。

    最后附上代码。

    #Import the Strange Dataset

    rawdata=readLines("Wealth and Health.txt")

    #Get the useful words

    data=unlist(strsplit(rawdata,"\\[\\{\"|\":\"|\",\"|\":\\[\\[|\\],\\[|\\]\\],\"|\\]\\]\\},\\{\"|\\]\\]\\}\\]"))

    data=data[which(data!="")]

    n=length(data)

    #Set index

    nameind=which(data=="name")

    regind=which(data=="region")

    incind=which(data=="income")

    popind=which(data=="population")

    lifind=which(data=="lifeExpectancy")

    endpoint=nameind-1

    endpoint=endpoint[2:180]

    endpoint[180]=45999

    name=data[nameind+1]

    region=data[regind+1]

    #An empty data.frame type

    initdfr=data.frame(name=rep(0,210),region=rep(0,210),year=1800:2009,income=rep(0,210),pop=rep(0,210),life=rep(0,210))

    #An string split function only working for the comma

    splt=function(x) return(as.numeric(unlist(strsplit(x,","))))

    #Linear interpolation function, for those zero data

    itpl=function(a)

    {

    ind=which(a>0)

    if (ind[1]>1)

    a[1:(ind[1]-1)]=rep(a[ind[1]],ind[1]-1)

    n=length(ind)

    if (ind[n]

    a[(ind[n]+1):length(a)]=rep(a[ind[n]],length(a)-ind[n])

    for (i in 1:(n-1))

    a[ind[i]:ind[i+1]]=rep(a[ind[i]],ind[i+1]-ind[i]+1)+(seq(ind[i],ind[i+1],1)-ind[i])*(a[ind[i+1]]-a[ind[i]])/(ind[i+1]-ind[i])

    return(a)

    }

    #Drag data information from words

    tbls=NULL

    for (i in 1:180)

    {

    dfr=initdfr

    dfr$name=rep(name[i],210)

    dfr$region=rep(region[i],210)

    for (j in (incind[i]+1):(popind[i]-1))

    {

    tmp=splt(data[j])

    ii=which(dfr$year==tmp[1])

    dfr$income[ii]=tmp[2]

    }

    for (j in (popind[i]+1):(lifind[i]-1))

    {

    tmp=splt(data[j])

    ii=which(dfr$year==tmp[1])

    dfr$pop[ii]=tmp[2]

    }

    for (j in (lifind[i]+1):endpoint[i])

    {

    tmp=splt(data[j])

    ii=which(dfr$year==tmp[1])

    dfr$life[ii]=tmp[2]

    }

    tbls=rbind(tbls,dfr)

    }

    #Two country with only one record, meaningless

    ind=which(tbls$name=="Mayotte")

    tbls=tbls[-ind,]

    ind=which(tbls$name=="Tokelau")

    tbls=tbls[-ind,]

    name=name[c(-28,-177)]

    region=region[c(-28,-177)]

    #Linear interpolation

    for (i in 1:178)

    {

    ind=(210*(i-1)+1):(i*210)

    tbls$income[ind]=itpl(tbls$income[ind])

    tbls$pop[ind]=itpl(tbls$pop[ind])

    tbls$life[ind]=itpl(tbls$life[ind])

    }

    require(ggplot2)

    #Draw function with ggplot2

    drawit=function(yr,scl=15)

    {

    ind=which(tbls$year==yr)

    d.f=data.frame(yr=yr)

    p=ggplot(aes(x=log(income),y=life,size=pop,colour=as.factor(region)),pch=21,data=tbls[ind,])

    p+geom_point(show_guide = FALSE)+

    geom_point(shape = 1,colour = "black",show_guide = FALSE)+

    xlim(5.5,11.7)+ylim(10,83)+scale_area(range = c(1, scl))+

    annotate("text", x=10, y=15, label = yr,size=30,color="grey")

    }

    #drawit(1800)

    #Automatically repeat the drawing procedure

    finaldraw=function(a,b)

    {

    for (i in 1:10)

    print(drawit(a))

    for (i in a:b)

    print(drawit(i))

    for (i in 1:10)

    print(drawit(b))

    }

    #finaldraw(1800,2009)

    require(animation)

    #sett ffmpeg in Windows = =||

    oopts = ani.options(ffmpeg = "D:/ffmpeg/bin/ffmpeg.exe")

    #Use the function from animation to make the final movie

    saveVideo({

    finaldraw(1800,2009)

    ani.options(interval = 0.1, nmax = 230)

    }, video.name = "HansRosling.mp4", other.opts = "-b 500k")

    更多相关内容
  • R语言之动态气泡图 刚开始学习R语言那会,被一个叫动态气泡图的图所吸引,因为看起来觉得很酷炫,当我把我的实验数据用动态气泡图展示给老师看的时候,我觉得他应该还是比较满意吧。 为了画这个图,我记得是写了不下...

    R语言之动态气泡图

    刚开始学习R语言那会,被一个叫动态气泡图的图所吸引,因为看起来觉得很酷炫,当我把我的实验数据用动态气泡图展示给老师看的时候,我觉得他应该还是比较满意吧。

    为了画这个图,我记得是写了不下10行代码,用到了一个叫“animation”的包,当时这个包还得去Github上下载,除此之外还需要下载一个叫“magic”还是什么的软件。

    今天为什么想分享一下气泡动态图呢,是因为我见到一个包,画气泡图就几行代码,另外还有交互效果,是不是很厉害。我真的是感慨R语言发展的太快。OK,话不多说,下面开始介绍这个包,这个包叫“plotly”。

    直接上代码:

    library(plotly)
    data(gapminder, package = "gapminder")
    gg <- ggplot(gapminder, aes(gdpPercap, lifeExp, color = continent)) +
      geom_point(aes(size = pop, frame = year, ids = country)) +
      scale_x_log10()
    ggplotly(gg)
    

    代码的重点是frame = year

    好的,来看结果吧~
    在这里插入图片描述
    点击Play你的数据就可以动起来了~

    是不是很简单呢?这个包还有其他酷炫的功能,感兴趣的同学自己去了解一下吧。

    好了,今天分享就到这,我去快乐地看文献了,下次再见~

    感兴趣的同学可以添加我的个人微信公众号“森林生态小小圈”。
    在这里插入图片描述

    展开全文
  • 动态气泡图,拿走不谢!

    千次阅读 2020-09-26 20:00:00
    许久没上公众号的后台,发现了不少变化。哈哈,不知不觉又鸽了快大半年,接下来多码字,立个Flag。本期给大家分享一个用D3.js实现的动态气泡图案例。也是之前小F了解D3.js时发现的,效...

    本期给大家分享一个用D3.js实现的动态气泡图案例。

    也是之前小F了解D3.js时发现的,效果大致如下。

    项目地址:

    https://observablehq.com/@unkleho/covid-19-bubble-chart-with-d3-render

    GitHub地址:https://github.com/unkleho/d3-render

    要想实现这个项目的话,首先需要安装Node.js以及npm,具体的安装步骤自行百度,还是比较简单的。

    接下来就可以安装Vue.js及Vue脚手架3.0。

    所以要想鼓捣一些高大上的可视化,前端的学习是必不可少的,默默的流下没有技术的泪水。

    # 安装Vue.js
    npm install vue
    
    # 安装Vue-cli3脚手架
    npm install -g @vue/cli
    

    如此便可以创建项目了。

    # 创建名为bubblechart的项目
    vue create bubblechart
    

    结果如下,选择默认模式即可。

    由于里面有eslint(编码规范)的存在,记得在配置文件package.json中添加下面的代码。

    "rules": {
        "no-unused-vars": "off",
        "no-undef": "off"
    }

    要不然会出现报错,无法运行。

    项目创建成功后,修改App.vue文件内容如下。

    <template>
      <div id="app">
        <svg id="bubble-chart" width="954" height="450" />
      </div>
    </template>
    
    <script>
    export default {
      name: 'App',
      components: {
      }
    }
    </script>
    
    <style></style>
    

    保存成功后,打开bubblechart文件夹下的终端,运行下面这个命令。

    npm run serve

    浏览器便会跳出一个标题为bubblechart的空白网页。

    安装一些项目依赖d3,d3-render,d3-selection,d3-transition,axios。

    npm install d3@5.16.0 --save-dev
    npm install d3-render@0.2.4 --save-dev
    npm install d3-selection@1.4.2 --save-dev
    npm install d3-transition@2.0.0 --save-dev
    npm install axios --save-dev

    最好是指定版本,要不然可能会报错。

    在main.js文件中引用axios,用于请求数据。

    import axios from 'axios'
    Vue.prototype.$axios = axios

    在App.vue的script标签中引用d3,d3-render。

    import * as d3 from "d3";
    import render from "d3-render";

    设置初始数据,各式各样的气泡颜色。

    data() {
        return {
          covidData: null,
          countries: null,
          colours: {
            pink: "#D8352A",
            red: "#D8352A",
            blue: "#48509E",
            green: "#02A371",
            yellow: "#F5A623",
            hyperGreen: "#19C992",
            purple: "#B1B4DA",
            orange: "#F6E7AD",
            charcoal: "#383838",
          }
        };
    }

    获取各地区的新冠数据,两个CSV文件放在Public文件夹下,可直接访问。

    methods: {
        async getdata() {
          //获取新冠数据      
          await this.$axios.get("data.csv").then((res) => {
            this.covidData = d3.csvParse(res.data);
          });
          //获取国家数据
          await this.$axios.get("countries.csv").then((res) => {
            this.countries = d3.csvParse(res.data);
          });
          //画图
          this.drawType();
        },
    }

    开始画图的操作,先定义一下画布大小以及各大洲的颜色。

    drawType() {
          //设置svg大小
          const width = 954;
          const height = 450;
          //设置各个大洲的参数
          const continents = [
            {
              id: "AF",
              name: "Africa",
              fill: this.colours.purple,
              colour: this.colours.charcoal,
            },
            {
              id: "AS",
              name: "Asia",
              fill: this.colours.yellow,
              colour: this.colours.charcoal,
            },
            {
              id: "EU",
              name: "Europe",
              fill: this.colours.blue,
              colour: this.colours.charcoal,
            },
            {
              id: "NA",
              name: "N. America",
              fill: this.colours.pink,
            },
            {
              id: "OC",
              name: "Oceania",
              fill: this.colours.orange,
              colour: this.colours.charcoal,
            },
            {
              id: "SA",
              name: "S. America",
              fill: this.colours.green,
              colour: this.colours.charcoal,
            },
          ];
    }

    定义圆圈组件,其中duration很重要,起到一个动画过渡的效果。

    //定义圆圈组件
    const circleComponent = ({ r, cx, cy, fill, duration }) => {
      return {
        append: "circle",
        r,
        cx,
        cy,
        fill,
        duration,
      };
    };

    定义文字组件,设置字体、大小、颜色等。

    //定义文字组件
    const textComponent = ({
        key,
        text,
        x = 0,
        y = 0,
        fontWeight = "bold",
        fontSize = "12px",
        textAnchor = "middle",
        fillOpacity = 1,
        colour,
        r,
        duration = 1000,
    }) => {
        return {
            append: "text",
            key,
            text,
            x,
            y,
            textAnchor,
            fontFamily: "sans-serif",
            fontWeight,
            fontSize,
            fillOpacity: { enter: fillOpacity, exit: 0 },
            fill: colour,
            duration,
            style: {
                pointerEvents: "none",
            },
        };
    };

    数值转换,对较大的数值进行处理。

    //对数值进行转换,比如42288变为42k
    const format = (value) => {
        const newValue = d3.format("0.2s")(value);
        if (newValue.indexOf("m") > -1) {
            return parseInt(newValue.replace("m", "")) / 1000;
        }
        return newValue;
    };

    动态变化标签信息,包含名称及数值。

    //将各地区名称长度和数值与圆圈大小相比较,实现信息动态变化
    const labelComponent = ({ isoCode, countryName, value, r, colour }) => {
        // Don't show any text for radius under 12px
        if (r < 12) {
            return [];
        }
        //console.log(r);
        const circleWidth = r * 2;
        const nameWidth = countryName.length * 10;
        const shouldShowIso = nameWidth > circleWidth;
        const newCountryName = shouldShowIso ? isoCode : countryName;
        const shouldShowValue = r > 18;
    
        let nameFontSize;
    
        if (shouldShowValue) {
            nameFontSize = shouldShowIso ? "10px" : "12px";
        } else {
            nameFontSize = "8px";
        }
    
        return [
            textComponent({
                key: isoCode,
                text: newCountryName,
                fontSize: nameFontSize,
                y: shouldShowValue ? "-0.2em" : "0.3em",
                fillOpacity: 1,
                colour,
            }),
            ...(shouldShowValue
                ? [
                    textComponent({
                        key: isoCode,
                        text: format(value),
                        fontSize: "10px",
                        y: shouldShowIso ? "0.9em" : "1.0em",
                        fillOpacity: 0.7,
                        colour,
                    }),
                ]
                : []),
        ];
    };

    设置气泡组件。

    //设置气泡组件
    const bubbleComponent = ({
        name,
        id,
        value,
        r,
        x,
        y,
        fill,
        colour,
        duration = 1000,
    }) => {
        return {
            append: "g",
            key: id,
            transform: {
                enter: `translate(${x + 1},${y + 1})`,
                exit: `translate(${width / 2},${height / 2})`,
            },
            duration,
            delay: Math.random() * 300,
            children: [
                circleComponent({ key: id, r, fill, duration }),
                ...labelComponent({
                    key: id,
                    countryName: name,
                    isoCode: id,
                    value,
                    r,
                    colour,
                    duration,
                }),
            ],
        };
    };

    划分数据的层次结构,生成气泡图的结构。

    后续的d.r、d.x、d.y数据都是从中获取的。

    //d3.pack - 创建一个新的圆形打包图
    //d3.hierarchy - 从给定的层次结构数据构造一个根节点并为各个节点指定深度等属性
    const pack = (data) =>
        d3
            .pack()
            .size([width - 2, height - 2])
            .padding(2)(d3.hierarchy({ children: data }).sum((d) => d.value));
    

    这一步不是太懂,以后慢慢了解。

    //生成气泡图表
    const renderBubbleChart = (selection, data) => {
        const root = pack(data);
        const renderData = root.leaves().map((d) => {
            return bubbleComponent({
                id: d.data.id,
                name: d.data.name,
                value: d.data.value,
                r: d.r,
                x: d.x,
                y: d.y,
                fill: d.data.fill,
                colour: d.data.colour,
            });
        });
        return render(selection, renderData);
    };
    
    const renderBubbleChartContainer = (data) => {
        return renderBubbleChart("#bubble-chart", data);
    };
    

    最后便可以加入数据,生成动态的气泡图表。

    对数据进行处理,进行日期限定及排序,以及选取相关的数据类型。

    //定义新冠数据
    const covidData_result = this.covidData;
    //定义各地区数据
    const countries_result = this.countries;
    
    //选择数据类型为所有确诊病例数量
    const dataKey = "total_cases";
    //定义开始时间及结束时间
    const startDate = new Date('2020-01-12')
    const endDate = new Date('2020-06-02')
    //d3.map - 创建一个新的空的 map 映射
    const dates = d3
        .map(this.covidData, (d) => d.date)
        .keys()
        .map((date) => new Date(date))
        .filter((date) => date >= startDate && date <= endDate)
        .sort((a, b) => a - b);
    //各大洲全选
    const selectedContinents = ["AF", "AS", "EU", "NA", "OC", "SA"];
    //最小数值
    const minimumPopulation = 0;
    //排序
    const order = "desc";
    
    //转换日期格式为2020-01-01
    const getIsoDate = (date) => {
        const IsoDate = new Date(date);
        return IsoDate.toISOString().split("T")[0];
    };
    
    //获取最终的数据
    function getDataBy({
        dataKey,
        date,
        selectedContinents,
        order,
        minimumPopulation,
    }) {
        return (
            covidData_result
                .filter((d) => d)
                .filter((d) => d.iso_code !== "OWID_WRL")
                // Filter out countries with populations under 1 million
                .filter((d) => d.population > parseInt(minimumPopulation))
                .filter((d) => {
                    return d.date === getIsoDate(date);
                })
                .filter((d) => d[dataKey])
                .filter((d) => {
                    const country = countries_result.find(
                        (c) => c.iso3 === d.iso_code
                    );
                    const continent = continents.find((c, i) => {
                        if (!country) {
                            return false;
                        }
    
                        return c.id === country.continentCode;
                    });
    
                    if (!continent) {
                        return false;
                    }
    
                    return selectedContinents.includes(continent.id);
                })
                .map((d) => {
                    const country = countries_result.find(
                        (c) => c.iso3 === d.iso_code
                    );
                    const continent = continents.find(
                        (c) => c.id === country.continentCode
                    );
    
                    const name = country.shortName || country.name;
    
                    return {
                        name,
                        id: country.iso3,
                        value: d[dataKey],
                        fill: continent.fill,
                        colour: continent.colour || "white",
                    };
                })
                .filter((d) => d.value !== "0.0")
                .sort(function (a, b) {
                    const mod = order === "desc" ? -1 : 1;
                    return mod * (a.value - b.value);
                })
        );
    }

    设置For循环延时,完成动态气泡图的实现。

    //延时执行,闭包
    for (var i = 0; i < dates.length; i++) {
        (function (i) {
            setTimeout(function () {
                const date = dates[i];
                console.log(date);
                const data = getDataBy({
                    dataKey,
                    date,
                    selectedContinents,
                    minimumPopulation,
                    order,
                });
                renderBubbleChartContainer(data);
            }, 2000 * i);
        })(i);
    };
    

    运行项目,打开浏览器,访问http://localhost:8080/

    可以看到酷炫的动态气泡图,昨天青岛又出现病例,疫情结束遥遥无期呀~

    项目的整个代码已经上传「GitHub」,访问链接如下。

    https://github.com/Tobby-star/bubble-chart

    将项目下载到本地,运行下面两行命令,即可运行。

    npm install
    npm run serve
    

    万水千山总是情,点个「点」行不行。

    展开全文
  • 在上一期的公众号文章里,我们通过动态气泡图展示了专利申请与地区经济的关系(动态气泡图:专利申请与地区经济),这其实是借鉴了汉斯·罗斯林的4分钟展示200个国家200年的兴衰历史([每日一图] 看了它,你也会爱上...

    在上一期的公众号文章里,我们通过动态气泡图展示了专利申请与地区经济的关系(动态气泡图:专利申请与地区经济),这其实是借鉴了汉斯·罗斯林的4分钟展示200个国家200年的兴衰历史([每日一图] 看了它,你也会爱上可视化),之前的公众号介绍了通过Excel(一图动览各国专利气质,附动态气泡图详解),Power View(动态气泡图之Power View作法详解)的动态气泡图作图详解,今天,我们来尝试通过python绘制,复制粘贴程序,一键出图。

    STEP 1 数据准备

    按照下图格式建立待读取的Excel文件:每一工作表包含一个维度的相应数据,例如,下表展示的为不同省份、年份对应的申请量数据:

    不同省份、年份对应的生产总值数据:

    不同工作表中,年份或地区的顺序可以存在不同,当展示的为地区数据时,是否有“省”、“市”的后缀并不影响程序的读取。

    STEP 2 适应性修改一键出图

    下载ImageMagick软件(百度网盘链接:https://pan.baidu.com/s/1mWZHh-EiTcYKp5RTMJ0CRw,密码:6fnr),用于帮助我们生成gif动图,安装完成后,请记住安装路径。

    程序及相关配置文件链接:https://pan.baidu.com/s/1LOo0SYBf5VtXyP4P5k1mSQ ,密码:aegt。

    将源程序,配置文件(matplotlibrc),以及需要可视化的数据复制到同一文件夹内,使用spyder打开配置文件,修改最后一行:填写ImageMagick安装路径,并删注释井号,如下图所示。

    在下文程序说明中第二部分,涉及Excel读取中,适应性修改待读取的Excel文件名和工作表名称(修改方式如作图详解 | 利用Python绘制技术功效图的方法(第二辑))

    使用“Excute in an external system terminal”的方式运行程序,运行后,程序会自动在当前文件夹下生成以横纵坐标为名字的gif文件。

    如果需要暂停或者恢复播放动画,按键盘上的空格键即可。

    程序说明

    程序共分为五个部分。

    第一部分,导入所需要的包:

    # -*- coding: utf-8 -*-

    importmatplotlib.pyplotasplt

    importnumpyasnp

    importmatplotlib.animation

    importmatplotlib.patchesasmpatches

    importpandasaspd

    importsys

    第二部分,读入excel文件:

    用户可根据实际需求修改此处的代码,以读取相应的sheet。根据实际需求,可以修改x轴数据,y轴数据,排序依据(即气泡大小表征的数据),以及显示多少个地区的标签。

    #读入excel文件,根据实际需求修改文件名称和sheet名称

    x_name='专利有效量'

    y_name='技术市场成交额(亿元)'

    sorted_by='申请量'

    areas_to_show=10

    df=pd.read_excel('分省年度数据GDP_最新.xls',sheetname=sorted_by,index_col='地区')

    df1=pd.read_excel('分省年度数据GDP_最新.xls',sheetname=y_name,index_col='地区')

    df2=pd.read_excel('分省年度数据GDP_最新.xls',sheetname=x_name,index_col='地区')

    第三部分,处理输入数据:

    在输入的地区数据中,可能只对排名靠前的几个地区感兴趣,这段代码涉及对各个地区的申请量进行排序挑选出前10名。输入的excel中有多个工作表,不能保证每个工作表的排序都是一致的,代码还涉及自动按照申请量排序后整理各个工作表的数据。

    #对输入数据按照指定的维度排序

    data_temp=[]

    foriindf.index:

    data_temp.append(df.loc[i].sum())

    df_merge=pd.DataFrame(index=df.index,columns=['sum'],data=data_temp)

    df_joined=df.join(df_merge)

    df_top10=df_joined.sort_values(by='sum',ascending=False).head(areas_to_show)

    df_top10=df_top10.drop('sum',1)

    drop_list=[]

    foriindf1.index:

    ifi[:2]indf_top10.index:

    pass

    else:

    drop_list.append(i)

    df1_temp=df1.drop(drop_list,0)

    index_list=[]

    foriindf_top10.index:

    forjindf1_temp.index:

    ifj[:2]== i[:2]:

    index_list.append(j)

    else:

    pass

    df1_temp=df1_temp.ix[index_list,:]

    drop_list=[]

    foriindf2.index:

    ifi[:2]indf_top10.index:

    pass

    else:

    drop_list.append(i)

    df2_temp=df2.drop(drop_list,0)

    index_list=[]

    foriindf_top10.index:

    forjindf2_temp.index:

    ifj[:2]== i[:2]:

    index_list.append(j)

    else:

    pass

    df2_temp=df2_temp.ix[index_list,:]

    第四部分,动画:

    完成每一帧动画的更新,具体操作为从数据源中提取下一年的新数据,用新数据更新气泡大小和位置,同时更新相应的年份文本标签。

    #动画函数

    defanimate(i):

    globalx,y,ax,s1,scale,t1,df,df1,df2,colors_list,key_flag,index_flag,df2_temp,df1_temp,text_list

    ifkey_flag:

    return

    ifindex_flag==0:

    t1.set_text(df.columns[-1])

    scale=3*np.sqrt(df[df.columns[-1]])

    x=df2[df2.columns[-1]]

    y=df1[df1.columns[-1]]

    offsets=[]

    fora,binzip(x,y):

    offsets.append((a,b))

    s1.set_offsets(offsets)

    s1.set_sizes(scale*2)

    s1.set_color(colors_list)

    foriintext_list:

    i.set_position((df2_temp.loc[i.get_text()][df2_temp.columns[len(df2_temp.columns)-index_flag-1]],df1_temp.loc[[jforjindf1_temp.indexifi.get_text()inj][0]][df1_temp.columns[len(df1_temp.columns)-index_flag-1]]))

    index_flag =1

    return

    scale=3*np.sqrt(df[df.columns[len(df.columns)-index_flag-1]])

    x=df2[df2.columns[len(df.columns)-index_flag-1]]

    y=df1[df1.columns[len(df.columns)-index_flag-1]]

    offsets=[]

    fora,binzip(x,y):

    offsets.append((a,b))

    s1.set_offsets(offsets)

    s1.set_sizes(scale*2)

    t1.set_text(df.columns[len(df.columns)-index_flag-1])

    foriintext_list:

    i.set_position((df2_temp.loc[i.get_text()][df2_temp.columns[len(df2_temp.columns)-index_flag-1]],df1_temp.loc[[jforjindf1_temp.indexifi.get_text()inj][0]][df1_temp.columns[len(df1_temp.columns)-index_flag-1]]))

    ifindex_flag <9:

    index_flag =1

    else:

    index_flag=0

    第五部分,主体程序:

    主要完成画布的初始化,动画的初始化,以及控制绘图和保存生成的gif动图。

    #主体程序,初始化绘图,动画设定,输出设置等

    fig=plt.figure(figsize=(12,7))

    ax=fig.add_subplot(111)

    fig.canvas.mpl_connect('key_press_event',press)

    scale=3*np.sqrt(df[df.columns[-1]])

    x=df2[df2.columns[-1]]

    y=df1[df1.columns[-1]]

    colors_list=[]

    forindexindf.index:

    foriinprovinces_four_parts:

    forjinprovinces_four_parts[i]:

    forkinj:

    ifindexink:

    colors_list.append(j[k])

    s1=ax.scatter(x, y, c=colors_list,s=scale*2,

    alpha=0.5)

    ax.set_ylim(0,1.0*max(df1.max()))

    ax.set_xlim(0,0.7*max(df2.max()))

    ax.grid()

    ax.legend(handles=[mpatches.Patch(color=colors_list[i],alpha=0.5,label=df.index[i])foriinrange(len(df.index))],bbox_to_anchor=(1.1,1),borderaxespad=0.)

    ax.set_title('2007-2016各省市'x_name'和'y_name'关系',size=20)

    ax.set_xlabel(x_name,size=20)

    ax.set_ylabel(y_name,size=20)

    t1=ax.text(0.05*max(df2.max()),0.85*max(df1.max()),df.columns[-1],size=40)

    text_list=[]

    fora,binzip(df2_temp.index,df1_temp.index):

    t2=ax.text(df2_temp.loc[a]['2007年'],df1_temp.loc[b]['2007年'],a,size=15,horizontalalignment='center',verticalalignment='center')

    text_list.append(t2)

    ani =matplotlib.animation.FuncAnimation(fig, animate, init_func=init_animation,frames=10,interval=1000)

    ani.save(x_name'VS'y_name'.gif', writer='imagemagick',fps=2)

    plt.show()

    展开全文
  • 动态气泡图

    千次阅读 2017-04-14 09:51:38
    原文地址:动态气泡图作者:数据化分析 (文/@数据化分析)   气泡图是一个将点表示为气泡(或圆圈)的散点图,与XY散点图类似,但可表现的数据信息量更多,最多可以表示五维(x 位置、 y 位置、大小、颜色和时间...
  • 下面就来说说和这两种非常相似的图表——散点图和气泡图。有需要的朋友们可以参考学习。 散点图和气泡图的实现 还是和之前一样,我们先把简单的画图框架搭起来,添加SVG画布: <!DOCTYPE html> <...
  • 先上图片:再上视频:最后上代码:importnumpyasnp importpandasaspd frommatplotlibimportpyplotasplt...
  • 利用动态气泡图进行数据分析

    千次阅读 2020-05-18 08:18:00
    作者:林骥 来源:林骥01你好,我是林骥。一个动态气泡图,可以展现多个维度的信息。比如说,要对比分析中国和美国从 1800 年以来每年的人口数量、人均收入和预期寿命,我...
  • 可视化:动态气泡图,拿走不谢!

    千次阅读 2020-09-29 18:22:58
    作者|小F来源 |法纳斯特(ID:walker398)头图 | CSDN下载自东方IC本期给大家分享一个用D3.js实现的动态气泡图案例。也是之前小F了解D3.js时发现的,效...
  • 一个动态气泡图,用css和javascript做的,希望对你有用
  • 主要介绍了CSS 动画实现动态气泡背景的方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 主要为大家详细介绍了js实现可爱的气泡特效,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • html5 svg动态气泡滑块特效是一款鼠标拖动气泡数字放大显示动画特效。
  • vue 动态气泡 CSS 动态气泡
  • 统计学家Hans Rosling在TED上关于《亚洲何时崛起》的演讲,其所采用的数据可视化展示方法可谓是近年来经典的可视化案例之一,动态气泡图生动的展示了中国和印度是如何在过去几十年拼命追赶欧美经济的整个过程。...
  • Python机器学习经典实例源码12.4动态气泡图
  • 我们正在创造一个有用的设置与对CSS3的多重背景和动画的力量动画按钮,无需使用JavaScript,通过此按钮包,您可以很容易地变成一个动画按钮,在您的网页上的任何链接只是指定一个类名,需要的朋友可以参考下
  • 从手机QQ中反编译取出的.9.png图片,可以直接在自己的IM项目中使用。
  • 下载直接解压文件用浏览器打开BubblesDemo.html即可(PS:该Demo使用...如果想更换图片,需要使用Photoshop切图放入img目录,为了方便小伙伴们切出合适的,我在demo下的img目录中放入了一个psd文件)
  • 学习chart.js中气泡图的基本用法和常用属性
  • 现在微信聊天少不了表情图片,这越有个性、独特的就越受大众喜爱,每每看到好看的...~自定义动态gif表情,在图片上加文字,你想写什么就写什么。微信动态表情制作软件,下载:http://www.leawo.cn/ND_upload.php?...
  • Python可视化-气泡图

    2020-12-10 12:55:30
    气泡图类似散点图,也是表示XY轴坐标之间的变化关系,也可以像彩色散点图给点上色。区别在于可以通过图中散点的大小来直观感受其所表示的数值大小。一、数据文件准备1、PeopleNumber.csvcity,people,priceNJ ,823,...
  • html5 svg动态气泡滑块特效是一款鼠标拖动气泡数字放大显示动画特效。
  • Ubuntu下,使用jQuery调用WebAPI获取MongoDB中存储的气泡图数据,并以气泡图(chart.js)方式展示
  • HTML5圆形气泡背景动画特效是一款基于HTML5 Canvas实现的气泡背景动画下载。
  • Document* {margin: 0;padding: 0;}.bg {position: absolute;top: 0;left: 0;width: 100%;height: 100%;overflow: hidden;background: linear-gradient(to bottom right, #50A3A2, #53E3A6);}li {position: absolute...
  • 概述气泡图,是散点图的变体,不同的是,散点图使用的是成组的X、Y值(二维),而气泡图使用的是成组的X、Y、Z值(三维),其Z值确定气泡的大小。如下气泡图来监视各调味品的单价、成本与库存订购量差: 2.示例2.1数据...
  • left: 'center', textStyle: { color: '#fff' } }, series: [ { type: 'effectScatter',//动态气泡 //type: 'scatter',//静态气泡 coordinateSystem: 'geo', data: mapData[n].sort(function (a, b) { return b....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,960
精华内容 3,984
关键字:

动态气泡图