लाखों बिंदुओं के मौजूद होने पर डेटा को अधिक कुशलता से प्लॉट करने के लिए सांख्यिकीय तरीके?


31

मुझे लगता है कि आर को प्लॉट तैयार करने में एक लंबा समय लग सकता है जब लाखों अंक मौजूद होते हैं - यह देखते हुए कि अंक व्यक्तिगत रूप से प्लॉट किए जाते हैं। इसके अलावा, इस तरह के प्लॉट अक्सर बहुत गुच्छेदार होते हैं और उपयोगी होने के लिए घने होते हैं। बिंदुओं में से कई ओवरलैप करते हैं और एक काले द्रव्यमान का निर्माण करते हैं और उस द्रव्यमान में अधिक बिंदुओं की साजिश रचने में बहुत समय व्यतीत होता है।

क्या मानक स्कैल्पलॉट में बड़े डेटा का प्रतिनिधित्व करने के लिए कोई सांख्यिकीय विकल्प हैं ? मैंने एक घनत्व प्लॉट पर विचार किया है, लेकिन अन्य विकल्प क्या हैं?n


1
रेखीय भूखंडों के साथ कुछ समाधानों के लिए, आँकड़े देखें ।stackexchange.com/questions/35220/…
whuber

जवाबों:


13

यह बिना किसी तैयार समाधान के साथ एक कठिन कार्य है (यह निश्चित रूप से है क्योंकि घनत्व प्लॉट इतना लुभावना है कि कोई भी वास्तव में परवाह नहीं करता है)। तो आप क्या कर सकते हैं?

यदि वे वास्तव में ओवरलैप करते हैं (अर्थात बिल्कुल समान एक्सएंडवाई निर्देशांक हैं) और आप अल्फा का उपयोग नहीं कर रहे हैं, तो सबसे अच्छा विचार सिर्फ ओवरलैप का उपयोग कम करना होगा unique(अल्फा के साथ, यह ऐसे समूहों पर अभिव्यक्त किया जा सकता है)।

यदि नहीं, तो आप मैन्युअल रूप से पास के पिक्सलों में निर्देशांक को गोल कर सकते हैं और पिछली विधि का उपयोग कर सकते हैं (फिर भी यह एक गंदा समाधान है)।

अंत में, आप सबसे घने क्षेत्रों में बिंदुओं को कम करने के लिए इसका उपयोग करने के लिए केवल एक घनत्व प्लॉट बना सकते हैं। दूसरी ओर यह ठीक उसी प्लॉट को नहीं बनाएगा और अगर ठीक से ट्यून नहीं किया गया तो कलाकृतियों को प्रस्तुत कर सकता है।


5
ओवरलैप को कम करने के साथ uniqueया गोलाई में पक्षपाती (भ्रामक) भूखंड हो सकते हैं। यह किसी तरह से कुछ ग्राफिकल साधनों जैसे कि लपट या सूरजमुखी के भूखंडों के माध्यम से ओवरलैप की मात्रा को इंगित करने के लिए महत्वपूर्ण है।
whuber

44

को देखो hexbin पैकेज है जो लागू कागज / दान कैर द्वारा विधि। पीडीएफ शब्दचित्र अधिक जानकारी के जो मैं नीचे उद्धृत किया है:

1 अवलोकन

हेक्सागोन बाइनिंग बड़े एन के साथ डेटासेट में स्ट्रू-ट्यूर की कल्पना करने के लिए उपयोगी बीवरिएट हिस्टोग्राम का एक रूप है। हेक्सागोन बिनिंग की अंतर्निहित अवधारणा बेहद सरल है;

  1. सेट (रेंज (x), रेंज (y) पर xy प्लेन हेक्सागोन्स के एक नियमित ग्रिड द्वारा tessellated है।
  2. प्रत्येक षट्भुज में गिरने वाले बिंदुओं की संख्या को एक डेटा संरचना में गिना और संग्रहीत किया जाता है
  3. n106

यदि ग्रिड के आकार और रंग रैंप में कटौती को एक चतुर तरीके से चुना जाता है, तो डेटा की अंतर्निहित संरचना की तुलना में द्विपदीय भूखंडों में उभरना चाहिए। हिस्टाग्राम पर लागू होने के रूप में हेक्सागोन बाइनिंग के लिए एक ही गुहा लागू होता है और द्विपदीय मापदंडों को चुनने में देखभाल का उपयोग किया जाना चाहिए।


4
वह अच्छा है। बस वही जो चिकित्सक ने आदेश किया।
रोमन लुसट्रिक

13
(+1) ब्याज की भी, smoothScatter {RColorBrewer}और densCols {grDevices}। मैं यह पुष्टि कर सकता हूं कि यह आनुवंशिक डेटा से हजार से मिलियन अंकों के साथ बहुत अच्छा काम करता है।
chl

2
यदि 3 डी डेटा है तो क्या होगा? (
स्कैल्प्लॉट

कुछ समय दूसरों को बचाने के लिए - मुझे स्मूथसैटर मिला, जैसा कि 2 टिप्पणियों का सुझाव दिया गया था, बहुत बेहतर चूक / कार्य करने के लिए।
चार्ली

16

मुझे यह स्वीकार करना चाहिए कि मैं आपके अंतिम पैराग्राफ को पूरी तरह से नहीं समझता:

"मैं एक घनत्व प्लॉट की तलाश में नहीं हूं (हालांकि वे अक्सर उपयोगी होते हैं), मैं एक साधारण प्लॉट कॉल के रूप में एक ही आउटपुट चाहता हूं लेकिन यदि संभव हो तो लाखों ओवरप्लॉट की तुलना में बहुत तेज है।"

यह भी स्पष्ट नहीं है कि आप किस प्रकार के कथानक (कार्य) की तलाश कर रहे हैं।

यह देखते हुए कि आपके पास मीट्रिक वैरिएबल हैं, आपको हेक्सागोन बिन्ड प्लॉट्स या सनफ्लॉवर प्लॉट्स उपयोगी मिल सकते हैं। आगे के संदर्भों के लिए, देखें


6

सवाल का एक और सीधा जवाब है, रैग पैकेज, जो ओपनगेल का उपयोग करके लाखों अंकों की साजिश कर सकता है। इसके अलावा, एक बिंदु आकार निर्दिष्ट करें (उदाहरण 3) और जनता के इन केंद्रों को अखंड ब्लॉकों के रूप में देखने के लिए ज़ूम इन करें, या ज़ूम इन करें और देखें कि अखंड क्या हुआ करते थे की संरचना देखें - बिंदु आकार स्थिर हैं लेकिन स्क्रीन पर उनके बीच की दूरी ज़ूमिंग पर निर्भर करें। अल्फा के स्तर का भी उपयोग किया जा सकता है।


5

यहाँ एक फ़ाइल है जिसे मैं कॉल करता हूँ bigplotfix.R। यदि आप इसे स्रोत करते हैं, तो यह एक आवरण को परिभाषित करेगा plot.xyजिसके लिए बहुत बड़े होने पर प्लॉट डेटा को "संपीड़ित" करता है। अगर इनपुट छोटा है तो रैपर कुछ नहीं करता है, लेकिन अगर इनपुट बड़ा है तो यह इसे विखंडू में तोड़ देता है और प्रत्येक चंक के लिए अधिकतम और न्यूनतम x और y मान प्लॉट करता है। सोर्सिंग bigplotfix.Rभी graphics::plot.xyरैपर को इंगित करने के लिए विद्रोह करता है (कई बार सोर्सिंग ठीक है)।

ध्यान दें कि plot.xyमानक प्लॉटिंग विधियों जैसे , और plot(), के लिए "वर्कहॉर्स" फ़ंक्शन है । इस प्रकार आप बिना किसी संशोधन के अपने कोड में इन कार्यों का उपयोग करना जारी रख सकते हैं, और आपके बड़े भूखंड अपने आप संपीड़ित हो जाएंगे।lines()points()

यह कुछ उदाहरण आउटपुट है। यह अनिवार्य रूप से plot(runif(1e5)), बिंदुओं और लाइनों के साथ, और यहां लागू किए गए "संपीड़न" के बिना और साथ है। "संपीड़ित अंक" भूखंड संपीड़न की प्रकृति के कारण मध्य क्षेत्र को याद करता है, लेकिन "संपीड़ित लाइनें" साजिश असम्पीडित मूल के बहुत करीब लगती है। समय png()डिवाइस के लिए हैं; कुछ कारणों pngसे डिवाइस में डिवाइस की तुलना में अंक बहुत तेज होते हैं X11, लेकिन गति-गति X11तुलनीय होती है ( मेरे प्रयोगों X11(type="cairo")की तुलना X11(type="Xlib")में धीमी थी )।

"bigplotfix.R" परीक्षण उत्पादन

इसका कारण मैंने यह लिखा है क्योंकि मैं plot()एक बड़े डेटासेट (जैसे एक WAV फ़ाइल) पर दुर्घटना से भाग कर थक गया था । ऐसे मामलों में मुझे साजिश रचने के लिए कई मिनट प्रतीक्षा करने और अपने R सत्र को एक संकेत के साथ समाप्त करने के बीच चुनना होगा (जिससे मेरा हालिया कमांड इतिहास और चर खो जाए)। अब अगर मैं प्रत्येक सत्र से पहले इस फ़ाइल को लोड करना याद रख सकता हूं, तो मैं वास्तव में इन मामलों में एक उपयोगी साजिश प्राप्त कर सकता हूं। थोड़ा चेतावनी संदेश इंगित करता है कि कब प्लॉट डेटा "संपीड़ित" किया गया है।

# bigplotfix.R
# 28 Nov 2016

# This file defines a wrapper for plot.xy which checks if the input
# data is longer than a certain maximum limit. If it is, it is
# downsampled before plotting. For 3 million input points, I got
# speed-ups of 10-100x. Note that if you want the output to look the
# same as the "uncompressed" version, you should be drawing lines,
# because the compression involves taking maximum and minimum values
# of blocks of points (try running test_bigplotfix() for a visual
# explanation). Also, no sorting is done on the input points, so
# things could get weird if they are out of order.
test_bigplotfix = function() {
  oldpar=par();
  par(mfrow=c(2,2))
  n=1e5;
  r=runif(n)
  bigplotfix_verbose<<-T
  mytitle=function(t,m) { title(main=sprintf("%s; elapsed=%0.4f s",m,t["elapsed"])) }
  mytime=function(m,e) { t=system.time(e); mytitle(t,m); }

  oldbigplotfix_maxlen = bigplotfix_maxlen
  bigplotfix_maxlen <<- 1e3;

  mytime("Compressed, points",plot(r));
  mytime("Compressed, lines",plot(r,type="l"));
  bigplotfix_maxlen <<- n
  mytime("Uncompressed, points",plot(r));
  mytime("Uncompressed, lines",plot(r,type="l"));
  par(oldpar);
  bigplotfix_maxlen <<- oldbigplotfix_maxlen
  bigplotfix_verbose <<- F
}

bigplotfix_verbose=F

downsample_xy = function(xy, n, xlog=F) {
  msg=if(bigplotfix_verbose) { message } else { function(...) { NULL } }
  msg("Finding range");
  r=range(xy$x);
  msg("Finding breaks");
  if(xlog) {
    breaks=exp(seq(from=log(r[1]),to=log(r[2]),length.out=n))
  } else {
    breaks=seq(from=r[1],to=r[2],length.out=n)
  }
  msg("Calling findInterval");
  ## cuts=cut(xy$x,breaks);
  # findInterval is much faster than cuts!
  cuts = findInterval(xy$x,breaks);
  if(0) {
    msg("In aggregate 1");
    dmax = aggregate(list(x=xy$x, y=xy$y), by=list(cuts=cuts), max)
    dmax$cuts = NULL;
    msg("In aggregate 2");
    dmin = aggregate(list(x=xy$x, y=xy$y), by=list(cuts=cuts), min)
    dmin$cuts = NULL;
  } else { # use data.table for MUCH faster aggregates
    # (see http://stackoverflow.com/questions/7722493/how-does-one-aggregate-and-summarize-data-quickly)
    suppressMessages(library(data.table))
    msg("In data.table");
    dt = data.table(x=xy$x,y=xy$y,cuts=cuts)
    msg("In data.table aggregate 1");
    dmax = dt[,list(x=max(x),y=max(y)),keyby="cuts"]
    dmax$cuts=NULL;
    msg("In data.table aggregate 2");
    dmin = dt[,list(x=min(x),y=min(y)),keyby="cuts"]
    dmin$cuts=NULL;
    #  ans = data_t[,list(A = sum(count), B = mean(count)), by = 'PID,Time,Site']
  }
  msg("In rep, rbind");
  # interleave rows (copied from a SO answer)
  s <- rep(1:n, each = 2) + (0:1) * n
  xy = rbind(dmin,dmax)[s,];
  xy
}

library(graphics);
# make sure we don't create infinite recursion if someone sources
# this file twice
if(!exists("old_plot.xy")) {
  old_plot.xy = graphics::plot.xy
}

bigplotfix_maxlen = 1e4

# formals copied from graphics::plot.xy
my_plot.xy = function(xy, type, pch = par("pch"), lty = par("lty"),
  col = par("col"), bg = NA, cex = 1, lwd = par("lwd"),
  ...) {

  if(bigplotfix_verbose) {
    message("In bigplotfix's plot.xy\n");
  }

  mycall=match.call();
  len=length(xy$x)
  if(len>bigplotfix_maxlen) {
    warning("bigplotfix.R (plot.xy): too many points (",len,"), compressing to ",bigplotfix_maxlen,"\n");
    xy = downsample_xy(xy, bigplotfix_maxlen, xlog=par("xlog"));
    mycall$xy=xy
  }
  mycall[[1]]=as.symbol("old_plot.xy");

  eval(mycall,envir=parent.frame());
}

# new binding solution adapted from Henrik Bengtsson
# https://stat.ethz.ch/pipermail/r-help/2008-August/171217.html
rebindPackageVar = function(pkg, name, new) {
  # assignInNamespace() no longer works here, thanks nannies
  ns=asNamespace(pkg)
  unlockBinding(name,ns)
  assign(name,new,envir=asNamespace(pkg),inherits=F)
  assign(name,new,envir=globalenv())
  lockBinding(name,ns)
}
rebindPackageVar("graphics", "plot.xy", my_plot.xy);

0

हो सकता है कि मैं अपने तरीके के लिए स्तब्ध हो जाऊं, मेरे एक शोध प्राध्यापक की बुरी यादें लोगों को अच्छे डेटा को श्रेणियों में अनुवाद करके फेंकने के लिए चिल्ला रही हैं (बेशक, मैं अब एक दिन में सहमत हूं), पता नहीं। वैसे भी, अगर आप एक स्कैल्पलॉट के बारे में बात कर रहे हैं, तो मेरे पास एक ही मुद्दे हैं। अब, जब मेरे पास संख्यात्मक डेटा है, तो विश्लेषण के लिए इसे वर्गीकृत करने के लिए मेरे लिए कोई मतलब नहीं है। लेकिन कल्पना करना एक अलग कहानी है। जो मैंने पाया है कि मेरे लिए सबसे अच्छा काम करता है पहले (1) कट फ़ंक्शन का उपयोग करके समूहों में अपने स्वतंत्र चर को तोड़ना है। आप समूहों की संख्या के साथ चारों ओर खेल सकते हैं, और फिर (2) बस IV के कट संस्करण के खिलाफ DV की साजिश रच रहे हैं। R उस घृणित बिखराव की जगह बॉक्स प्लॉट उत्पन्न करेगा। मैं सलाह देता हूं कि आउटलेयर को हटाने की साजिश रचें (प्लॉट कमांड में आउटलाइन = FALSE विकल्प का उपयोग करें)। फिर, मैं वर्गीकृत करके और फिर विश्लेषण करके पूरी तरह से अच्छा संख्यात्मक डेटा बर्बाद करूँगा। बहुत सारे मुद्दे जो कर रहे हैं। हालांकि मुझे पता है कि यह बहस का एक मार्मिक विषय है। लेकिन विशेष रूप से डेटा से बाहर कुछ दृश्य समझ बनाने के लक्ष्य के लिए विशेष रूप से ऐसा करना, इससे मुझे कोई नुकसान नहीं हुआ है। मैंने 10M के रूप में बड़े पैमाने पर डेटा प्लॉट किया है और फिर भी इस विधि से इसका अर्थ निकालने में कामयाब रहा। उम्मीद है की वो मदद करदे! सादर! इसे देखा है। मैंने 10M के रूप में बड़े पैमाने पर डेटा प्लॉट किया है और फिर भी इस विधि से इसका अर्थ निकालने में कामयाब रहा। उम्मीद है की वो मदद करदे! सादर! इसे देखा है। मैंने 10M के रूप में बड़े पैमाने पर डेटा प्लॉट किया है और फिर भी इस विधि से इसका अर्थ निकालने में कामयाब रहा। उम्मीद है की वो मदद करदे! सादर!


0

बड़ी समय श्रृंखला के लिए, मुझे स्मूथस्कैटर (बेस आर नो कम का हिस्सा) से प्यार हुआ है । मुझे अक्सर कुछ अतिरिक्त डेटा शामिल करने होते हैं, और मूल प्लॉट एपीआई को संरक्षित करना वास्तव में मददगार होता है, उदाहरण के लिए:

set.seed(1)
ra <- rnorm(n = 100000, sd = 1, mean = 0)
smoothScatter(ra)
abline(v=25000, col=2)
text(25000, 0, "Event 1", col=2)

जो आपको देता है (यदि आप डिजाइन को क्षमा करते हैं):

तितर बितर उदाहरण

यह हमेशा उपलब्ध है और विशाल डेटासेट के साथ अच्छी तरह से काम करता है, इसलिए कम से कम आपके पास एक नज़र रखना अच्छा है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.