基于Processing的数据可视化
虽然数据可视化领域有很多成熟、界面友好、功能强大的软件产品(例如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的数据可视化的更多相关文章
- 基于matplotlib的数据可视化 - 笔记
1 基本绘图 在plot()函数中只有x,y两个量时. import numpy as np import matplotlib.pyplot as plt # 生成曲线上各个点的x,y坐标,然后用一 ...
- ARDUNIO IMU processing姿态数据可视化
https://www.arduino.cn/thread-42852-1-1.html 关键数据打包 float roll, pitch, heading; Serial.print("O ...
- 基于matplotlib的数据可视化 - 饼状图pie
绘制饼状图的基本语法 创建数组 x 的饼图,每个楔形的面积由 x / sum(x) 决定: 若 sum(x) < 1,则 x 数组不会被标准化,x 值即为楔形区域面积占比.注意,该种情况会出现 ...
- 基于matplotlib的数据可视化 - 热图imshow
热图: Display an image on the axes. 可以用来比较两个矩阵的相似程度 mp.imshow(z, cmap=颜色映射,origin=垂直轴向) imshow( X, cma ...
- 基于matplotlib的数据可视化 - 等高线 contour 与 contourf
contour 与contourf 是绘制等高线的利器. contour - 绘制等高线 contourf - 填充等高线 两个的返回值值是一样的(return values are the sam ...
- 基于matplotlib的数据可视化 -
matplotlib.pyplot(as mp or as plt)提供基于python语言的绘图函数 引用方式: import matplotlib.pyplot as mp / as plt 本章 ...
- 基于matplotlib的数据可视化 - 三维曲面图gca
1 语法 ax = plt.gca(projection='3d')ax.plot_surface(x,y,z,rstride=行步距,cstride=列步距,cmap=颜色映射) gca(**kwa ...
- 基于matplotlib的数据可视化 - 柱状图bar
柱状图bar 柱状图常用表现形式为: plt.bar(水平坐标数组,高度数组,宽度比例,ec=勾边色,c=填充色,label=图例标签) 注:当高度值为负数时,柱形向下 1 语法 bar(*args, ...
- 基于matplotlib的数据可视化(图形填充fill fill_between) - 笔记(二)
区域填充函数有 fill(*args, **kwargs) 和fill_between() 1 绘制填充多边形fill() 1.1 语法结构 fill(*args, **kwargs) args - ...
随机推荐
- linux rman shell
# make direcory for backset file and scripts file,in my case /backup/db_bak cd /backup/db_bak mkdi ...
- iOS中打印系统详细日志
Q:如何打印当前的函数和行号? A:我们可以在打印时使用一些预编译宏作为打印参数,来打印当前的函数和行号.如: 1 NSLog(@"%s:%d obj=%@", __func__, ...
- C++ sizeof总结
关键字sizeof的作用是返回对象或类型占用的内存字节数,返回值是size_t. 基本数据类型占用的字节数:(32位系统) char 1字节 bool 1字节 short 2字节 int 4字节 lo ...
- Javascript实现图片库效果
思路: 无序列表加载图片文件.用img标签加载一张图片作为占位符.当点击照片链接时,改变<a>元素的href属性.并且阻止浏览器的默认行为. 动态改变描述文字,在图片下方增加P标签.通过获 ...
- Python传参数最简单易懂的描述
关于,python的传参,很多人会搞得一头雾水,我也跟朋友讨论多次,最终通过实验,得到结论. 一.所有传递都是引用传递 二.在函数内使用[变量名]=,相当于定义啦一个局部变量 OK,一段简单的 ...
- sql 命令操作用法
---恢复内容开始--- 远程登录数据库: mysql -u root -p 要求输入密码 ============== 查看数据库: show databases;============= 选择数 ...
- 解决SDK Manager无法更新问题
因为google被封了,导致Android SDK Manager无法更新,解决方案如下: 1.选择tools->options,跳出Settings页面 2.设置HTTP Proxy代理,设置 ...
- RPMForge——Quick Start build system
How to setup multimedia on CentOS-5 CentOS ships with basic sound support for audio content encoded ...
- PDF抽取文字 C# with Adobe API
前提是PDF里面是有文字的! 一次性取得所有页内容: /// <summary> /// 改进前取得所有页的所有word /// </summary> /// <para ...
- 2016022610 - redis列表命令集合
参考网址:http://www.yiibai.com/redis/redis_lists.html Redis列表是简单的字符串列表,排序插入顺序.您可以在头部或列表的尾部Redis的列表添加元素.列 ...