Introdução a Visualização de Dados: Teoria e Prática Nicole Sultanum Jornada de Informática na Biodiversidade LNCC 13 de Fevereiro de 2015
Golden rules of visualization tools (by Enrico Bertini) Ferramentas vão mudar! Não existe o melhor absoluto para todo mundo http://fellinlovewithdata.com/guides/data-vis-beginners-toolkit-2
Ferramentas Excel Infogr.am R (ggplot2) Tableau D3 Processing VTK/Paraview
Excel Não primariamente, ou somente visualização Difundido Mais poderoso do que se pensa mas não é tão simples sair do básico. http://www.excelcharts.com/ http://www.excelcharts.com/blog/excel-dashboard-catchment-area/#prettyphoto
infogr.am Ferramenta Web para criação de charts básicos Free (com assinatura para versão PRO) Simples!
R (ggplot2) Não primariamente, ou somente visualização Biblioteca de plotting do R Diagramas prédefinidos, mas consideravelmente customizáveis Somente 2D Python tem biblioteca similar: matplotlib! http://www.statmethods.net/advgraphs/index.html qplot(x, y, data=, color=, shape=, size=, alpha=, geom=, method=, formula=, facets=, xlim=, ylim= xlab=, ylab=, main=, sub=)! http://ggplot2.org/
Visualização sem programação (drag & drop)! Mais madura, profissional e completa ferramenta de visualização do mercado Complexa! Cara! Mas tem licença para estudantes J! Tableau
Javascript (Web) Específico para visualização D3 Data Driven Documents Flexibilidade, grande comunidade, extensiva lista de exemplos http://d3js.org/
Processing Java-like (originalmente dextro.org Image by Marius Watz: https://wildinwoods.wordpress.com/category/infographics-data-visualization/ baseado em Java, hoje porta para várias outras plataformas) Desenvolvimento gráfico de propósito geral (não somente visualização de dados) 2D e 3D https://www.flickr.com/photos/8203774@n06/2286119870/sizes/o/ http://processing.org/
VTK / Paraview
Comparação entre ferramentas Dados Complexid. Expressiv. Plataforma Free? Linguagens Excel T Desktop VBA Infogr.am T Web (limitado) --- R (ggplot2) T Desktop (GPL-2) R Tableau TM Dskt, Web (15d trial) --- D3 TMG (3) Web (BSD) Javascript Processing TMG3 Dskt, Web (MIT) Java/JS/Python VTK/ Paraview 3 (TMG) Dskt (Web) (BSD) C++ T Tabela, M Mapa/Campo G Grafo, 3 Dados 3D
D3 vs. Processing D3! Processing! Tipos de gráfico Vetorial Raster (primariamente) Suporte a 3D +- Sim Suporte a Web Sim Sim (javascript) Interação Via eventos Ciclo de updates Comunidade no Stk. Ov. (complexidade?) 818 páginas 158 páginas Aprendizado Complicado! Simples J Eficiência/Escala Centenas de formas Após overhead inicial, milhares de formas com performance constante
Introdução a Visualização de Dados: Teoria e Prática Prática D3
Objetivo Aprender a utilizar recursos básicos da tecnologia implementando exemplos simples Incremental vários pequenos exercícios Aprender o bastante para ser autosuficiente (ou mais próximo disso)
D3 D3 allows you to bind arbitrary data to a Document Object Model (DOM), and then apply data-driven transformations to the document. D3 is not a monolithic framework that seeks to provide every conceivable feature. Instead, D3 solves the crux of the problem: efficient manipulation of documents based on data. Javascript SVG HTML CSS
SVG Gráficos vetoriais por linguagem de marcação rect! circle! ellipse! line! gradient! text! polygon! polyline! path! g (grupo de formas) www.w3schools.com/svg/
CSS Define estilos e layout para liguagens de marcação web.class #id Color opacity Border Font-style Font-family Text-align www.w3schools.com/css/
D3 Conceitos básicos D3 não é uma biblioteca de desenho: Mapeamento de um objeto de dado a um elemento do DOM Declarativo, não imperativo Você não desenha, mas sim, especifica como quer que o desenho seja feito Fluxo básico Criar um canvas SVG Seleção de elementos de atuação no DOM (elementos podem ainda não existir). Mapear seleção aos dados: Para cada elemento; Especificação dos atributos visuais, classes ; Associar a eventos;
D3 rodando o primeiro programa Código-fonte! Output!
D3 rodando o primeiro programa em detalhes Array de dados Criação de um canvas SVG no <body> (onde as formas são efetivamente desenhadas) Criação dos elementos rect (retângulos); Um para cada dado contido no array data! (i.e. mapeamento dados <-> gráficos!) Funcão definindo comportamento do atributo (poderia ter sido uma função anônima)
D3 rodando o primeiro programa em detalhes d3.select("body")! Seleciona o elemento <body> do nó principal do documento (DOM) <body>.append("svg")! Adiciona um novo elemento do tipo SVG à seleção (no caso, o nó <body> do DOM) <svg>.attr( width, 400)! Adiciona um novo atributo ao elemento correspondente https://github.com/mbostock/d3/wiki/selections
D3 rodando o primeiro programa em detalhes svg.selectall("rect")! Seleciona (dentro do nó svg) todos os elementos de tag rect. Gera uma seleção de elementos de DOM (neste caso, vazia!)! <sel>.data(data)! Mapeia a seleção de DOMs ao conjunto de dados especificado. <sel>.enter()! Se #dados > #elementos DOM, um novo placeholder é criado: <d>.append("rect")! Utiliza o placeholder criado e adiciona um elemento rect. <d>.attr( width,20)! Modifica atributo width com valor constante, 20. http://alignedleft.com/tutorials/d3/binding-data <d>.attr( width,20)! bblablbllablal
select() selectall()! Seleções! d3.select(selector)! d3.selectall(selector)!! var svg = body.select("svg");! var rects = svg.selectall(".bars");!!!! d3.select(node)! d3.selectall(node)!! body.select(svg);! svg.selectall(rects);! https://github.com/mbostock/d3/wiki/selections Operações sobre seleções! selection.append(name)! "selection.append( text ); //ou svg:text!! selection.attr(name[,val])! "selection.attr( width, 100); "selection.attr( width ); //returns 100!! selection.style(name[,val[,prior]])! "selection.style({'stroke': 'black',! " " " 'stroke-width': 2,! " " "});!! selection.classed(name[,val])! "selection.classed( bars, true);!! // Tem mais! Checa o link ali do lado!
select() selectall()! Operações sobre seleções! selection.append(name)! "selection.append( text ); //ou svg:text!! selection.attr(name[,val])! "selection.attr( width, 100); "selection.attr( width ); //returns 100!! selection.style(name[,val[,prior]])! "selection.style({'stroke': 'black',! " " " 'stroke-width': 2});!! selection.classed(name[,val])! "selection.classed( bars, true);!! // Tem mais! Checa o link ali do lado! Valores podem ser funções selection.attr( x,! "function(d,i){! " "//d <- dado! " "//i <- indice! " "return i * 25;! "});!!! function()! function(d) function(d,i) http://bost.ocks.org/mike/circles/
Exercício 1 5 min Adaptar o código fornecido para criar um diagrama de barras representando os dados; function()! function(d) function(d,i) Y = ybottom- height ybottom selection.attr(name[,val])! "selection.attr( width, 100); "selection.attr( x, function(d,i){! " "return i * 25;! "});!!! selection.style(name[,val[,prior]])! "selection.style({'stroke': 'black',! " " " 'stroke-width': 2,! " " " 'fill': red });!
Exercício 1
attr()! atributos específicos atributos globais https://developer.mozilla.org/pt-br/docs/web/svg
text()!
style() classed() ==
Exercício 2 7 min Adicionar texto com o valor numérico de cada dado; separar o estilo.
Exercício 2
Reorganizando
d3.scale()! Scales are functions that map from an input domain to an output range domain (input) range (output) Quantitativa Domínio contínuo d3.scale.linear()! d3.scale.pow()! d3.scale.quantile()! d3.scale.threshold()!.! Ordinal Domínio Discreto d3.scale.ordinal()! Temporal Domínio temporal d3.time.scale()! https://github.com/mbostock/d3/wiki/scales
d3.scale() Mapeando um atr. quantitativo a uma escala numérica (e.g. pixels) Mapeando um atr. ordinal a uma escala numérica Mapeando um atr. quantitativo a cor (divergente) Mapeando um atr. ordinal a cor
d3.scale.ordinal() d3.scale.category10()! d3.scale.category20()! d3.scale.category20b()! d3.scale.category20c()! + ColorBrewer! Every ColorBrewer Scale: http://bl.ocks.org/mbostock/5577023 https://github.com/mbostock/d3/wiki/ordinal-scales http://colorbrewer2.org/
Exercício 3 10 min Use escalas para mapear: No. items [1,10] ao comprimento [10,250];! Dados [0,9] à altura das barras [20,150];! Dados a cor [#253494, #41b6c4, #c2e699]!
Exercício 3
Reorganizando
d3.svg! Helper functions to generate and manage SVG shapes Formas d3.svg.line()!! g.append("path")!.attr("d", line);!! d3.svg.area()! d3.svg.arc()! d3.svg.chord()!! Eixos!! d3.svg.axis()!! axis.scale([scale])! axis.orient([orientation])! axis.ticks([arguments ])! axis.tickvalues([values])! axis.tickformat([format])! Brush d3.svg.brush()!! https://github.com/mbostock/d3/wiki/svg
d3.svg.axis() axis.scale([scale])!! A função d3.scale() que descreve o eixo axis.orient([orientation])! [ top, bottom, left, right ]! Posicionamento dos ticks (marcações). https://github.com/mbostock/d3/wiki/svg-axes axis.ticks([arguments ])! axis.tickvalues([values])! Determina número de marcações. Em tickvalues(), um array arbitrário de marcações pode ser informado, e.g.: axis.tickvalues([2,4,5,8,10]);!
http://bost.ocks.org/mike/bar/3/ d3.svg.axis()
Exercício 4 10min Adicionar eixos X e Y ao diagrama de barras: axis.tickvalues([values])!
Exercício 4
Interatividade selection.on(type[, listener[, capture]])! Example adapted from: http://www.stator-afm.com/tutorial/d3-js-mouse-events/ Qualquer evento DOM suportado pelo seu browser: mousedown! mouseenter! mouseleave! mousemove! mouseout! mouseup! Entre outros https://developer.mozilla.org/en-us/docs/ Web/Events#Standard_events
Interatividade selection.on(type[, listener[, capture]])! this à a seleção correspondente When a function is used as an event handler, its this is set to the element the event fired from. https://developer.mozilla.org/en-us/docs/web/javascript/reference/operators/this Example adapted from: http://synthesis.sbecker.net/articles/2012/07/10/learning-d3-part-3-animation-interaction
Exercício 5 5min Highlight de barras com borda vermelha quando mouse passar por cima; sem borda quando sair.
Exercício 5
Formatos de dados - JSON JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. Objeto Membros Array Par id (string) : valor http://www.json.org/
Formatos de dados - Tabelas CSV Comma Separated Values TSV Tab Separated Values Date,Wound,Field,Disease 5/1854,0,95,105 6/1854,0,40,95 7/1854,0,140,520 8/1854,20,150,800 9/1854,220,230,740 10/1854,305,310,600 11/1854,480,290,820 12/1854,295,310,1100 1/1855,230,460,1440 Date Wound Field Disease 5/1854 0 95 105 6/1854 0 40 95 7/1854 0 140 520 8/1854 20 150 800 9/1854 220 230 740 10/1854 305 310 600 11/1854 480 290 820 12/1854 295 310 1100 1/1855 230 460 1440
Carregando Tabelas! d3.csv() d3.tsv()! Função de carregamento url [opc] parse Callback após dados dados por linha carregados Forma alternativa Dados são sempre carregados como string por isso a necessidade de um parser customizado por linha Object {! "sepallength: 5.1, "sepalwidth: 5.1, "petallength: 1.4, "petalwidth: 0.2,! "species: "setosa"! }! https://github.com/mbostock/d3/wiki/csv
Carregando dados! d3.csv() d3.tsv() d3.json() d3.xml() Dados são carregados assincronamente, de forma que o resto do código da página possa carregar enquanto os dados são processados. Código que depende dos dados deve ser rodado a partir da função de callback (passada na solicitação do carregamento), enquanto o resto do código roda imediatamente. https://github.com/mbostock/d3/wiki/requests
Funções auxiliares para arrays De Javascript arr.sort([comparefunction])! arr.pop()! arr.push(el1,..., eln)! arr.reverse()! arr.slice([begin[, end]])! arr.indexof(el[,fromid=0])! arr.filter(callback[, arg])! arr.foreach(callback[, arg])!! De D3 d3.min(array[, accessor])! d3.max(array[, accessor])! d3.extent(array[, accessor])! d3.sum(array[, accessor])! d3.median(array[, accessor])!! https://developer.mozilla.org/en-us/docs/web/ JavaScript/Reference/Global_Objects/Array https://github.com/mbostock/d3/wiki/arrays
Exercício 06 (final) - scatterplot Carregar dados do iris.tsv e gerar o gráfico abaixo: (X-sepalWidth, Y-sepalLength, hue-species)
Exercício 06 (final) - scatterplot (X- sepalwidth, Y- sepallength, hue- species) d3.min(array[, accessor])! d3.max(array[, accessor])! d3.extent(array[, accessor])! d3.scale.category10()!
Exercício 06 (final) - scatterplot
Outros tópicos Mapas Layouts radiais Grafos Projeções de mapa Transições Brushing & Linking https://github.com/mbostock/d3/wiki/gallery
Outros tópicos Dados dinâmicos Mapas Layouts radiais Grafos Projeções de mapa Transições Brushing & Linking http://bl.ocks.org/mbostock
Excelente introdução a D3 Murray, Scott. Interactive data visualization for the Web. " O'Reilly Media, Inc.", 2013.
http://d3js.org/
Introdução a Visualização de Dados: Teoria e Prática Prática Processing
Processing Gráficos raster baseado em opengl Inicialmente construído em cima de Java, hoje roda também em: Javascript (Web), Android, Python, Ruby. Construído para: Ser simples API minimal, low entry point Expressividade gráfico-interativa Portanto.. bastante popular entre artistas gráficos Inspirado/baseado em OpenGL Propósito geral, i.e. não exclusivo de visualização de dados
Processing Onde baixar: processing.org! (Windows, Linux, Mac OS)
Processing IDE Play/Stop Arquivos de um sketch Output (java, javascript, Android ) Adicionar/ remover arquivos ao sketch Também é possível usar o Eclipse (com alguns ajustes ) Console Erros
Primeiro programa em Processing Abrir a referência: processing.org/reference/
Formas Primitivas ellipse(a, b, c, d)! arc(a, b, c, d, start, stop)! rect(a, b, c, d)! line(x1, y1, x2, y2)! bezier(x1, y1, x2, y2, x3, y3, x4, y4)! quad(x1, y1, x2, y2, x3, y3, x4, y4)! triangle(x1, y1, x2, y2, x3, y3)! text(c, x, y)!...! Algumas têm mais de um construtor rect(a, b, c, d)! rect(a, b, c, d, r)! rect(a, b, c, d, tl, tr, br, bl)! processing.org/reference/
! Configurações são globais como em OpenGL fill()! nofill()! stroke()! nostroke()! strokeweight()! strokejoin()! strokecap()! colormode()//rgb, HSB!...!!
! Configurações são globais como em OpenGL fill()! nofill()! stroke()! nostroke()! strokeweight()! strokejoin()! strokecap()! colormode()//rgb, HSB!...!!
Configurações são globais como em OpenGL! ellipsemode()! rectmode()!
color é um tipo primitivo R:250 G:0 B:0 A:255 R:200 G:200 B:200A:255 R:0 G:0 B:255 A:100
Exercício 1 10min 400x600 200 270 100 180 ellipse(cx,cy,rx,ry)! rect(x,y,w,h)! triangle(x1,y1,x2,y2,x3,y3)! arc(cx,cy,rx,ry,a1,a2)!! 55 90 150 100 430 480 490 540 fill(g)! fill(r,g,b)! nofill()! stroke(g)! stroke(r,g,b)! strokeweight(w)! nostroke()!!
Exercício 1
Carregando dados https://processing.org/reference/loadtable_.html
Mapeamentos (com dados) map(value, start1, stop1, start2, stop2)! lerp(start,stop,amt)! lerpcolor(start,stop,amt)!
Exercício 2 20 min Carregar o arquivo mammals.csv e criar um scatterplot simples com: X = Weight Average (kg) (float) Y = Length Average (m) (float) cor = Conservation Level (int) 40,200,40 255,0,0 0 100,100,255 Conservation Level Status! 1 - Least Concern 2 Vulnerable 3 - Near Threatened 4 - Endangered 5 Critically Endangered 6 Extinct 0 - Data Deficient map(value, start1, stop1,! " start2, stop2)! lerp(start,stop,amt)! lerpcolor(start,stop,amt)!
Exercício 2
Interatividade Capturando eventos de mouse/teclado
Interatividade Eventos de mouse/teclado Mouse! mouseclicked()! mousedragged()! mousemoved()! mousepressed()! mousepressed! mousereleased()! mousewheel()! Teclado! keypressed()! keypressed! keyreleased()! keytyped()!!
Interatividade Acessando valores de mouse/keyboard Mouse! mousex! mousey! pmousex! pmousey! (pmousex,pmousey) (mousex,mousey) Teclado! key! keycode! UP, DOWN, LEFT, RIGHT, ALT, CONTROL, SHIFT, PAGE_UP, PAGE_DOWN, HOME, END! l L! <left click>
Exercício 3 5 min Modificar o Ex. 2 para exibir a coordenada (X,Y) do espaço de dados (não pixels) quando mouse clicar em um ponto dentro do diagrama. mousex! mousey!
Modificar o Ex. 2 para exibir a coordenada (X,Y) do espaço de dados (não pixels) quando mouse clicar em um ponto dentro do diagrama. Exercício 3
Um outro exercício bem mais trabalhoso! Não se preocupe, não faremos ele hoje! Modificar o Ex. 2 para, quando o mouse fizer hover em um ponto no gráfico, exibir um popup com a ordem do elemento correspondente. Por que é complicado?! Raster -> pixels, não elementos É preciso fazer testes de colisão manualmente Oclusão! Quem está na frente? Gestão de ordem de desenho Carnivora Nessas horas o D3 começa a se tornar bem mais vantajoso para visualização de dados
O que mais é possível fazer: Bibliotecas diversas: Processamento de imagem Mapas GUI Dispositivos de input leap motion, kinect, etc. Simulação física 2D Shaders 3D Áudio Visão computacional Bancos de dados SQL Charts Entre outros https://processing.org/reference/libraries/
https://processing.org/reference/ Mais métodos
https://processing.org/tutorials/ Tutoriais