虽然数据可视化领域有很多成熟、界面友好、功能强大的软件产品(例如Tableau、VIDI、NodeXL等),但是借助Processing我们可以基于Java语言框架进行丰富多元的可视化编程,熟悉了Processing也可以说是上一学期Topics课程的最大收获,以另一种方式将数据重新组织、统计并以可视化界面展现出来。今天再看其他资料时碰巧看到XX对Processing的支持,颇感亲切,所以决定把上学期Topics的作业过程记录下来。

可视化内容是从Databank下载的217个国家、6个地区的7项统计数据。要求从通过数据可视化看出每个指标的变化趋势、所选不同国家之间的对比情况、不同时间段数据变化、不同地区所包含国家的统计数据对比等。

– Electricity production (kWh)
– Electricity production from renewable sources (kWh)
– Electric power consumption (kWh)
– Electric power consumption (kWh per capita)
– CO2 emissions (metric tons per capita)
– CO2 emissions (kt)
– Population, total

数据文件如下:

最终可视化结果如下:

源码如下:

 import processing.core.*;
import processing.data.*;
import processing.event.*;
import processing.opengl.*; import controlP5.*;
import java.lang.Math; import java.util.HashMap;
import java.util.ArrayList;
import java.io.File;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException; public class TCS1 extends PApplet { ControlP5 cp5; FloatTable data, dataRegion;
float dataMin, dataMax;
float volumnMax; float plotX1, plotY1;
float plotX2, plotY2;
float labelX, labelY; int yearMin, yearMax;
int[] years;
int yearInterval = 3; int showRow = 6;
int showRegionRow = 0; int yearStartCol = 8; //Integrator[] interpolators; PFont plotFont;
DropdownList dropCountry, dropCate, dropRegion; boolean isNormalOn = true;
boolean isGroupOn = false;
boolean isCompareOn = false; int groupMode = 1;
static final int GROUP_MODE_REGIONS = 1;
static final int GROUP_MODE_DECADES = 2; IntList listCompare = new IntList();
int[][] compareColors = new int[300][3];
int cateCompare = 0; int[] decadeYearIndex = new int[4];
String[] decadeYearStr = new String[4]; public void setup() {
size(1200, 750); cp5 = new ControlP5(this);
data = new FloatTable("data.tsv");
dataRegion = new FloatTable("region.tsv"); years = PApplet.parseInt(data.getColumnNames()); yearMin = years[yearStartCol];
yearMax = years[years.length - 1]; //init decade year
for (int i=7; i>3; i--) {
decadeYearStr[7-i] = data.getColumnNames()[i];
decadeYearIndex[7-i] = 7-i;
} interpolators = new Integrator[data.getColumnCount()];
for(int col=yearStartCol; col=weishu; i--) {
maxStr += "0";
eachStr += "0";
}
eachStr += "0" + firstNum;
maxStr += firstNum + "";
}
else {
for (int i=-1; i>=weishu+1; i--) {
maxStr += "0";
eachStr += "0";
}
eachStr += "0" + firstNum;
maxStr += firstNum + "";
}
}
else if (weishu == 0) {
if (firstNum != 10) {
maxStr = "0."+firstNum;
eachStr = "0.0" + firstNum;
}
else {
maxStr = firstNum / 10 + "";
eachStr = "0." + firstNum / 10;
}
}
else if (weishu == 1) {
if (firstNum != 10) {
maxStr = firstNum + "";
eachStr = "0." + firstNum;
}
else {
maxStr = firstNum + "";
eachStr = firstNum / 10 + "";
}
}
else {
maxStr += firstNum + "";
eachStr += firstNum + "";
for (int i=1; i= 10) {
if (weishu == 0) {
volumnNumbers[i] = currentFirstNum / 100 + "";
}
else {
volumnNumbers[i] = currentFirstNum / pow(10, 2-weishu) + "";
}
}
else if (PApplet.parseFloat(currentFirstNum) / 10 >= 1) {
volumnNumbers[i] += "0.";
for (int j=-1; j>weishu-1;j--) {
volumnNumbers[i] += "0";
}
volumnNumbers[i] += currentFirstNum;
}
else {
volumnNumbers[i] += "0.";
for (int j=-1; j>weishu-2;j--) {
volumnNumbers[i] += "0";
}
volumnNumbers[i] += currentFirstNum;
}
}
else if (weishu == 1) {
if (PApplet.parseFloat(currentFirstNum) / 10 >= 1) { volumnNumbers[i] = (currentFirstNum / 10) + "." + (currentFirstNum - ((currentFirstNum / 10) * 10));
}
else {
volumnNumbers[i] = "0."+currentFirstNum;
}
}
else {
volumnNumbers[i] = currentFirstNum + "";
for (int j=0; j 0) {
if (v > 100) {
return String.format("%.0f", v);
}
else if (v > 10) {
return String.format("%.2f", v);
}
else if (v > 1) {
return String.format("%.3f", v);
}
else {
return String.format("%.4f", v);
}
}
return "";
} public void drawDataPoints(int row) {
for (int col=yearStartCol; col3; col--) {
if (data.isValid(row, col)) {
float value = data.getFloat(row, col);
System.out.println(value);
float x = map(decadeYearIndex[7-col], -0.7f, 3.7f, plotX1, plotX2);
float y = map(value, 0, volumnMax, plotY2, plotY1); rect(x-(recWidth / 2), y, recWidth, plotY2 - y); text(value, x, y - 20);
}
}
} public void drawDataLine(int row) {
beginShape();
//stroke(23, 23, 23);
for (int col=yearStartCol; col= data.length)) {
throw new RuntimeException("There is no row " + rowIndex);
}
if ((col < 0) || (col >= data[rowIndex].length)) {
throw new RuntimeException("Row " + rowIndex + " does not have a column " + col);
}
// end training wheels return data[rowIndex][col];
} public boolean isValid(int row, int col) {
//System.out.println("data[6].length" + data[6].length);
if (row < 0) return false;
if (row >= rowCount) return false;
//if (col >= columnCount) return false;
if (col >= data[row].length) return false;
if (col < 0) return false;
if(data[row][col] == 0) return false;
return !Float.isNaN(data[row][col]);
} public float getColumnMin(int col) {
float m = Float.MAX_VALUE;
for (int row = 0; row < rowCount; row++) {
if (isValid(row, col)) {
if (data[row][col] < m) {
m = data[row][col];
}
}
}
return m;
} public float getColumnMax(int col) {
float m = -Float.MAX_VALUE;
for (int row = 0; row < rowCount; row++) {
if (isValid(row, col)) {
if (data[row][col] > m) {
m = data[row][col];
}
}
}
return m;
} public float getRowMin(int row) {
float m = Float.MAX_VALUE;
for (int col = 0; col < columnCount; col++) {
if (isValid(row, col)) {
if (data[row][col] < m) {
m = data[row][col];
}
}
}
return m;
} public float getRowMax(int row) {
float m = -Float.MAX_VALUE;
for (int col = 0; col < columnCount; col++) {
if (isValid(row, col)) {
if (data[row][col] > m) {
m = data[row][col];
}
}
}
return m;
} public float getTableMin() {
float m = Float.MAX_VALUE;
for (int row = 0; row < rowCount; row++) {
for (int col = 0; col < columnCount; col++) {
if (isValid(row, col)) {
if (data[row][col] < m) {
m = data[row][col];
}
}
}
}
return m;
} public float getTableMax() {
float m = -Float.MAX_VALUE;
for (int row = 0; row < rowCount; row++) {
for (int col = 0; col < columnCount; col++) {
if (isValid(row, col)) {
if (data[row][col] > m) {
m = data[row][col];
}
}
}
}
return m;
} public boolean hasData(int row, int startCol) {
boolean hasData = false;
for (int col = startCol; col < columnCount; col++) {
//System.out.println("row="+row+" col="+col+" isValid="+isValid(row, col));
if (isValid(row, col)) {
hasData = true;
break;
}
}
return hasData;
} public float getRowMin(int row, int startCol) {
float m = Float.MAX_VALUE;
for (int col = startCol; col < columnCount; col++) { //System.out.println("row="+row+" col="+col+" isValid="+isValid(row, col));
if (isValid(row, col)) {
if (data[row][col] < m) {
m = data[row][col];
}
}
}
return m;
} public float getRowMax(int row, int startCol) {
float m = -Float.MAX_VALUE;
for (int col = startCol; col < columnCount; col++) {
//System.out.println("row="+row+" col="+col+" isValid="+isValid(row, col));
if (isValid(row, col)) {
if (data[row][col] > m) {
m = data[row][col];
}
}
}
return m;
} public float getRowMin(int row, int startCol, int endCol) {
float m = Float.MAX_VALUE;
for (int col = startCol; col < endCol + 1; col++) { //System.out.println("row="+row+" col="+col+" isValid="+isValid(row, col));
if (isValid(row, col)) {
if (data[row][col] < m) {
m = data[row][col];
}
}
}
return m;
} public float getRowMax(int row, int startCol, int endCol) {
float m = -Float.MAX_VALUE;
for (int col = startCol; col < endCol + 1; col++) {
//System.out.println("row="+row+" col="+col+" isValid="+isValid(row, col));
if (isValid(row, col)) {
if (data[row][col] > m) {
m = data[row][col];
}
}
}
return m;
}
}
class Integrator { final float DAMPING = 0.5f;
final float ATTRACTION = 0.2f; float value;
float vel;
float accel;
float force;
float mass = 1; float damping = DAMPING;
float attraction = ATTRACTION;
boolean targeting;
float target; Integrator() { } Integrator(float value) {
this.value = value;
} Integrator(float value, float damping, float attraction) {
this.value = value;
this.damping = damping;
this.attraction = attraction;
} public void set(float v) {
value = v;
} public void update() {
if (targeting) {
force += attraction * (target - value);
} accel = force / mass;
vel = (vel + accel) * damping;
value += vel; force = 0;
} public void target(float t) {
targeting = true;
target = t;
} public void noTarget() {
targeting = false;
}
}
static public void main(String[] passedArgs) {
String[] appletArgs = new String[] { "TCS1" };
if (passedArgs != null) {
PApplet.main(concat(appletArgs, passedArgs));
} else {
PApplet.main(appletArgs);
}
}
}

基于Processing的数据可视化的更多相关文章

  1. 基于matplotlib的数据可视化 - 笔记

    1 基本绘图 在plot()函数中只有x,y两个量时. import numpy as np import matplotlib.pyplot as plt # 生成曲线上各个点的x,y坐标,然后用一 ...

  2. ARDUNIO IMU processing姿态数据可视化

    https://www.arduino.cn/thread-42852-1-1.html 关键数据打包 float roll, pitch, heading; Serial.print("O ...

  3. 基于matplotlib的数据可视化 - 饼状图pie

    绘制饼状图的基本语法 创建数组 x 的饼图,每个楔形的面积由 x / sum(x) 决定: 若 sum(x) < 1,则 x 数组不会被标准化,x 值即为楔形区域面积占比.注意,该种情况会出现 ...

  4. 基于matplotlib的数据可视化 - 热图imshow

    热图: Display an image on the axes. 可以用来比较两个矩阵的相似程度 mp.imshow(z, cmap=颜色映射,origin=垂直轴向) imshow( X, cma ...

  5. 基于matplotlib的数据可视化 - 等高线 contour 与 contourf

    contour 与contourf 是绘制等高线的利器. contour  - 绘制等高线 contourf - 填充等高线 两个的返回值值是一样的(return values are the sam ...

  6. 基于matplotlib的数据可视化 -

    matplotlib.pyplot(as mp or as plt)提供基于python语言的绘图函数 引用方式: import matplotlib.pyplot as mp / as plt 本章 ...

  7. 基于matplotlib的数据可视化 - 三维曲面图gca

    1 语法 ax = plt.gca(projection='3d')ax.plot_surface(x,y,z,rstride=行步距,cstride=列步距,cmap=颜色映射) gca(**kwa ...

  8. 基于matplotlib的数据可视化 - 柱状图bar

    柱状图bar 柱状图常用表现形式为: plt.bar(水平坐标数组,高度数组,宽度比例,ec=勾边色,c=填充色,label=图例标签) 注:当高度值为负数时,柱形向下 1 语法 bar(*args, ...

  9. 基于matplotlib的数据可视化(图形填充fill fill_between) - 笔记(二)

    区域填充函数有 fill(*args, **kwargs) 和fill_between() 1  绘制填充多边形fill() 1.1 语法结构 fill(*args, **kwargs) args - ...

随机推荐

  1. 译文:如何使用SocketAsyncEventArgs类(How to use the SocketAsyncEventArgs class)

      转载自: http://blog.csdn.net/hulihui/article/details/3244520 原文:How to use the SocketAsyncEventArgs c ...

  2. android自定义样式大全:shape,selector,layer-list,style,动画全部内容

    原文:http://keeganlee.me/post/android/20150830 以下摘取了部分内容: shape 一般用shape定义的xml文件存放在drawable目录下,若项目没有该目 ...

  3. SQL内外左右交叉连接

    什么是连接查询? 概念:根据两个表或多个表的列之间的关系,从这些表中查询数据. 目的:实现多个表查询操作. 一般是用作关联两张或两张以上的数据表时用的.看起来有点抽象,我们举个例子,做两张表:学生表( ...

  4. rest例子

    http://www.xdemo.org/spring-restful/(可用) http://www.open-open.com/lib/view/open1389075258125.html(有例 ...

  5. 原生Javascript实现控制DIV属性

    写在前面: 从事前端工作已有一年之久,因为工作的性质,不太涉及JS方面,所以自己的JS水平一直处于小白阶段,工作闲暇之余,在网上找了一些小项目,希望练练手,促进自己成长.这是第一篇,后续还会有很多记录 ...

  6. 开源字体包缩减font-spider

    最近公司产品用微软雅黑,被告~  领导要求产品后台系统必须更换字体,美工给了个宋体,个人觉得太丑,就网上搜了些处理方法使用 CSS属性 @font-face 自定义字体, 最后决定用 思源黑体 (思源 ...

  7. CSS图片去色

    .imgFilter { filter: grayscale(100%); -webkit-filter: grayscale(100%); -moz-filter: grayscale(100%); ...

  8. hdu 1396 Counting Triangles(递推)

    Counting Triangles Problem Description Given an equilateral triangle with n thelength of its side, p ...

  9. Svn与Git的区别

    把第一条理解到位思想到位了做起来才会有的放矢,其他几条都是用的时候才能体会到 1) 最核心的区别Git是分布式的,而Svn不是分布的.能理解这点,上手会很容易,声明一点Git并不是目前唯一的分布式版本 ...

  10. 小爬虫。爬取网站多页的通知标题并存取在txt文档里。

    爬取网页中通知标题的内容展示: this is  1  page!<精算学综合>科目考试参考大纲2016年上半年研究生开题报告评议审核结果公示[答辩]2016下半年研究生论文答辩及学位评定 ...