আর-তে দুটি হিস্টোগ্রাম একসাথে কীভাবে প্লট করা যায়?


221

আমি আর ব্যবহার করছি এবং আমার দুটি ডেটা ফ্রেম রয়েছে: গাজর এবং শসা। প্রতিটি ডেটা ফ্রেমের একটি একক সংখ্যাসূচক কলাম রয়েছে যা সমস্ত পরিমাপক গাজরের দৈর্ঘ্য (মোট: 100 কে গাজর) এবং শসা (মোট: 50 কে শসা) তালিকাবদ্ধ করে।

আমি একই প্লটে দুটি হিস্টগ্রাম - গাজরের দৈর্ঘ্য এবং শসাগুলির দৈর্ঘ্য - প্লট করতে চাই। তারা ওভারল্যাপ করে, তাই আমার ধারণা আমারও কিছুটা স্বচ্ছতা দরকার। প্রতিটি গ্রুপের উদাহরণগুলির সংখ্যা পৃথক হওয়ায় আমারও আপেক্ষিক ফ্রিকোয়েন্সি পরম সংখ্যা নয়।

এর মতো কিছু সুন্দর লাগবে তবে কীভাবে এটি আমার দুটি টেবিল থেকে তৈরি করা যায় তা আমি বুঝতে পারি না:

ওভারল্যাপড ঘনত্ব


বিটিডব্লিউ, আপনি কোন সফ্টওয়্যার ব্যবহারের পরিকল্পনা করছেন? মুক্ত উত্সের জন্য, আমি gnuplot.info [gnuplot] সুপারিশ করব । এর ডকুমেন্টেশনে, আমি বিশ্বাস করি আপনি যা চান তা করার জন্য আপনি নির্দিষ্ট কৌশল এবং নমুনা স্ক্রিপ্ট পাবেন।
noel aye

1
আমি ট্যাগটিকে পরামর্শ হিসাবে র ব্যবহার করছি (এটি পরিষ্কার করার জন্য সম্পাদিত পোস্ট)
ডেভিড বি

1
কেউ এই থ্রেডে এটি করতে কিছু কোড স্নিপেট পোস্ট করেছেন: stackoverflow.com/questions/3485456/…
নিকো

উত্তর:


194

আপনি যে চিত্রটির সাথে লিঙ্ক করেছেন সেটি হিস্টোগ্রাম নয়, ঘনত্বের বক্ররেখার জন্য।

আপনি যদি ggplot এ পড়তে থাকেন তবে আপনি কেবলমাত্র হারিয়ে যাচ্ছেন তা হ'ল আপনার দুটি ডেটা ফ্রেমকে একটি দীর্ঘের সাথে একত্রিত করা।

সুতরাং, আসুন আপনার কাছে যা আছে তার মতো কিছু দিয়ে শুরু করুন, ডেটার দুটি পৃথক সেট এবং তাদের একত্রিত করুন।

carrots <- data.frame(length = rnorm(100000, 6, 2))
cukes <- data.frame(length = rnorm(50000, 7, 2.5))

# Now, combine your two dataframes into one.  
# First make a new column in each that will be 
# a variable to identify where they came from later.
carrots$veg <- 'carrot'
cukes$veg <- 'cuke'

# and combine into your new data frame vegLengths
vegLengths <- rbind(carrots, cukes)

এর পরে, এটি অকারণে যদি আপনার ডেটাটি ইতিমধ্যে দীর্ঘ ফর্ম্যাটে থাকে তবে আপনার প্লটটি তৈরি করতে আপনার কেবল একটি লাইন প্রয়োজন।

ggplot(vegLengths, aes(length, fill = veg)) + geom_density(alpha = 0.2)

এখানে চিত্র বর্ণনা লিখুন

এখন, আপনি যদি সত্যিই হিস্টোগ্রাম চান না তবে নীচেরগুলি কাজ করবে। নোট করুন যে আপনাকে অবশ্যই ডিফল্ট "স্ট্যাক" যুক্তি থেকে অবস্থান পরিবর্তন করতে হবে। আপনি সম্ভবত এটি মিস করতে পারেন যদি আপনার ডেটা কেমন হবে সে সম্পর্কে আপনার যদি ধারণা না থাকে তবে। একটি উচ্চতর আলফা সেখানে আরও ভাল দেখায়। আরও মনে রাখবেন যে আমি এটি ঘনত্বের হিস্টোগ্রাম তৈরি করেছি। y = ..density..এটিকে গণনাতে ফিরিয়ে আনা সহজ remove

ggplot(vegLengths, aes(length, fill = veg)) + 
   geom_histogram(alpha = 0.5, aes(y = ..density..), position = 'identity')

এখানে চিত্র বর্ণনা লিখুন


8
আপনি যদি হিস্টোগ্রামের সাথে থাকতে চান তবে ব্যবহার করুন ggplot(vegLengths, aes(length, fill = veg)) + geom_bar(pos="dodge")। এটি ম্যাটল্যাবের মতো ইন্টারলেলেস্ট হিস্টোগ্রাম তৈরি করবে।
এমবিকিউ

1
উত্তরের জন্য থেক্স! 'পজিশন = "পরিচয়" "অংশটি আসলে গুরুত্বপূর্ণ যেমনটি অন্যথায় বারগুলি সজ্জিত থাকে যা ঘনত্বের সাথে মিলিত হলে বিভ্রান্তিকর হয় যা ডিফল্টরূপে" পরিচয় "বলে মনে হয়, যেমন স্ট্যাকের বিপরীতে ওভারলেড হয়।
ছায়া

265

এখানে বেস গ্রাফিক্স এবং আলফা-মিশ্রণ (যা সমস্ত গ্রাফিক্স ডিভাইসে কাজ করে না) ব্যবহার করে একটি আরও সহজ সমাধান রয়েছে:

set.seed(42)
p1 <- hist(rnorm(500,4))                     # centered at 4
p2 <- hist(rnorm(500,6))                     # centered at 6
plot( p1, col=rgb(0,0,1,1/4), xlim=c(0,10))  # first histogram
plot( p2, col=rgb(1,0,0,1/4), xlim=c(0,10), add=T)  # second

মূলটি হ'ল রঙগুলি আধা স্বচ্ছ।

সম্পাদনা করুন, আরও দু'বছর পরে : এই মাত্র একটি উত্সাহ পেয়েছে, আমি অনুমান করি যে কোডটি আলফা-মিশ্রণ হিসাবে এতটা রঞ্জক হিসাবে কী উত্পন্ন করে তার একটি ভিজ্যুয়াল যুক্ত করতে পারি:

এখানে চিত্র বর্ণনা লিখুন


6
+1 আপনাকে সকলকে ধন্যবাদ, এটিকে কি মসৃণ গিস্টগ্রামে রূপান্তর করা যেতে পারে (যেমন had.co.nz/ggplot2/ographicics/55078149a733dd1a0b42a57faf847036.png )?
ডেভিড বি

3
আপনি plotআদেশগুলি পৃথক করলেন কেন ? আপনি histকমান্ডগুলিতে এই সমস্ত অপশন রাখতে পারেন এবং এটি দুটি লাইনে দুটি করে রাখতে পারেন।
জন

@ জন আপনি কিভাবে এটি করবেন?
হ্যালো ওয়ার্ল্ড

plotকমান্ডের অপশনগুলি হিস্ট কমান্ডের মধ্যে সরাসরি বলেছিলাম Put কোড পোস্ট করা মন্তব্যগুলির জন্য যা তা নয়।
জন

44

এখানে আমি লিখেছি এমন একটি ফাংশন যা ওভারল্যাপিং হিস্টোগ্রামগুলি উপস্থাপন করতে ছদ্ম-স্বচ্ছতা ব্যবহার করে

plotOverlappingHist <- function(a, b, colors=c("white","gray20","gray50"),
                                breaks=NULL, xlim=NULL, ylim=NULL){

  ahist=NULL
  bhist=NULL

  if(!(is.null(breaks))){
    ahist=hist(a,breaks=breaks,plot=F)
    bhist=hist(b,breaks=breaks,plot=F)
  } else {
    ahist=hist(a,plot=F)
    bhist=hist(b,plot=F)

    dist = ahist$breaks[2]-ahist$breaks[1]
    breaks = seq(min(ahist$breaks,bhist$breaks),max(ahist$breaks,bhist$breaks),dist)

    ahist=hist(a,breaks=breaks,plot=F)
    bhist=hist(b,breaks=breaks,plot=F)
  }

  if(is.null(xlim)){
    xlim = c(min(ahist$breaks,bhist$breaks),max(ahist$breaks,bhist$breaks))
  }

  if(is.null(ylim)){
    ylim = c(0,max(ahist$counts,bhist$counts))
  }

  overlap = ahist
  for(i in 1:length(overlap$counts)){
    if(ahist$counts[i] > 0 & bhist$counts[i] > 0){
      overlap$counts[i] = min(ahist$counts[i],bhist$counts[i])
    } else {
      overlap$counts[i] = 0
    }
  }

  plot(ahist, xlim=xlim, ylim=ylim, col=colors[1])
  plot(bhist, xlim=xlim, ylim=ylim, col=colors[2], add=T)
  plot(overlap, xlim=xlim, ylim=ylim, col=colors[3], add=T)
}

এখানে অন্য কোনো উপায় এটা করতে স্বচ্ছ রঙের জন্য আর সমর্থন ব্যবহার

a=rnorm(1000, 3, 1)
b=rnorm(1000, 6, 1)
hist(a, xlim=c(0,10), col="red")
hist(b, add=T, col=rgb(0, 1, 0, 0.5) )

ফলাফলগুলি এরকম কিছু দেখার শেষ করে: বিকল্প পাঠ


সমস্ত গ্রাফিক্স ডিভাইসে উপলভ্য বিকল্পের জন্য +1 (যেমন postscript)
লেনা

31

ইতিমধ্যে সুন্দর উত্তরগুলি রয়েছে, তবে আমি এটি যুক্ত করার কথা ভেবেছিলাম। আমার কাছে ভালই লাগছে. (@ ডির্ক থেকে এলোমেলো সংখ্যা অনুলিপি করা হয়েছে)। library(scales)প্রয়োজন `

set.seed(42)
hist(rnorm(500,4),xlim=c(0,10),col='skyblue',border=F)
hist(rnorm(500,6),add=T,col=scales::alpha('red',.5),border=F)

ফলাফল হলো...

এখানে চিত্র বর্ণনা লিখুন

আপডেট: এই ওভারল্যাপিং ফাংশনটি কারও কারও পক্ষে কার্যকর হতে পারে।

hist0 <- function(...,col='skyblue',border=T) hist(...,col=col,border=border) 

আমি ফলাফল hist0দেখতে চেয়ে সুন্দর দেখতে পেয়েছিhist

hist2 <- function(var1, var2,name1='',name2='',
              breaks = min(max(length(var1), length(var2)),20), 
              main0 = "", alpha0 = 0.5,grey=0,border=F,...) {    

library(scales)
  colh <- c(rgb(0, 1, 0, alpha0), rgb(1, 0, 0, alpha0))
  if(grey) colh <- c(alpha(grey(0.1,alpha0)), alpha(grey(0.9,alpha0)))

  max0 = max(var1, var2)
  min0 = min(var1, var2)

  den1_max <- hist(var1, breaks = breaks, plot = F)$density %>% max
  den2_max <- hist(var2, breaks = breaks, plot = F)$density %>% max
  den_max <- max(den2_max, den1_max)*1.2
  var1 %>% hist0(xlim = c(min0 , max0) , breaks = breaks,
                 freq = F, col = colh[1], ylim = c(0, den_max), main = main0,border=border,...)
  var2 %>% hist0(xlim = c(min0 , max0),  breaks = breaks,
                 freq = F, col = colh[2], ylim = c(0, den_max), add = T,border=border,...)
  legend(min0,den_max, legend = c(
    ifelse(nchar(name1)==0,substitute(var1) %>% deparse,name1),
    ifelse(nchar(name2)==0,substitute(var2) %>% deparse,name2),
    "Overlap"), fill = c('white','white', colh[1]), bty = "n", cex=1,ncol=3)

  legend(min0,den_max, legend = c(
    ifelse(nchar(name1)==0,substitute(var1) %>% deparse,name1),
    ifelse(nchar(name2)==0,substitute(var2) %>% deparse,name2),
    "Overlap"), fill = c(colh, colh[2]), bty = "n", cex=1,ncol=3) }

ফলাফল

par(mar=c(3, 4, 3, 2) + 0.1) 
set.seed(100) 
hist2(rnorm(10000,2),rnorm(10000,3),breaks = 50)

হয়

এখানে চিত্র বর্ণনা লিখুন


24

আপনি কীভাবে এটি "ক্লাসিক" আর গ্রাফিকগুলিতে করতে পারেন তার একটি উদাহরণ এখানে রয়েছে:

## generate some random data
carrotLengths <- rnorm(1000,15,5)
cucumberLengths <- rnorm(200,20,7)
## calculate the histograms - don't plot yet
histCarrot <- hist(carrotLengths,plot = FALSE)
histCucumber <- hist(cucumberLengths,plot = FALSE)
## calculate the range of the graph
xlim <- range(histCucumber$breaks,histCarrot$breaks)
ylim <- range(0,histCucumber$density,
              histCarrot$density)
## plot the first graph
plot(histCarrot,xlim = xlim, ylim = ylim,
     col = rgb(1,0,0,0.4),xlab = 'Lengths',
     freq = FALSE, ## relative, not absolute frequency
     main = 'Distribution of carrots and cucumbers')
## plot the second graph on top of this
opar <- par(new = FALSE)
plot(histCucumber,xlim = xlim, ylim = ylim,
     xaxt = 'n', yaxt = 'n', ## don't add axes
     col = rgb(0,0,1,0.4), add = TRUE,
     freq = FALSE) ## relative, not absolute frequency
## add a legend in the corner
legend('topleft',c('Carrots','Cucumbers'),
       fill = rgb(1:0,0,0:1,0.4), bty = 'n',
       border = NA)
par(opar)

এটির সাথে একমাত্র ইস্যুটি হিস্টোগ্রাম ব্রেকগুলি সারিবদ্ধ করা থাকলে এটি ম্যানুয়ালি করতে হবে (যুক্তিগুলিতে প্রেরণে hist) এটি আরও ভাল দেখায় ।


খুব সুন্দর. তাই আমার যে এক স্মরণ করিয়ে stackoverflow.com/questions/3485456/...
জর্জ Dontas

এটি আপআপ করা হচ্ছে কারণ আপনার উত্তর ggplotদুটিই হিস্টোগ্রামে যথেষ্ট আলাদা আলাদা নমুনার আকার থাকলে এই উত্তরটি কেবলমাত্র একটিই (এতে থাকাগুলি ছাড়াও ) for
মাইকেলচিরিকো

আমি এই পদ্ধতিটি পছন্দ করি, নোট করুন যে আপনি ব্রেকগুলি সেক () দিয়ে সংজ্ঞায়িত করে সিঙ্ক্রোনাইজ করতে পারেন। উদাহরণস্বরূপ:breaks=seq(min(data$some_property), max(data$some_property), by=(max_prop - min_prop)/20)
ডেরুইজটার

17

এখানে কেবল জিপিপ্লাট 2 এর মতো সংস্করণটি আমি কেবল বেস বেসে দিয়েছি @ আমি @ নলগ্লোব থেকে কিছু অনুলিপি করেছি।

ডেটা উত্পন্ন

carrots <- rnorm(100000,5,2)
cukes <- rnorm(50000,7,2.5)

আপনাকে এটি জিপিপ্লট 2 এর মতো কোনও ডেটা ফ্রেমে রাখার দরকার নেই। এই পদ্ধতির অপূর্ণতা হ'ল আপনাকে প্লটের বিশদ বিবরণে আরও অনেক কিছু লিখতে হবে। সুবিধাটি হ'ল প্লটের আরও বিশদে আপনার নিয়ন্ত্রণ রয়েছে।

## calculate the density - don't plot yet
densCarrot <- density(carrots)
densCuke <- density(cukes)
## calculate the range of the graph
xlim <- range(densCuke$x,densCarrot$x)
ylim <- range(0,densCuke$y, densCarrot$y)
#pick the colours
carrotCol <- rgb(1,0,0,0.2)
cukeCol <- rgb(0,0,1,0.2)
## plot the carrots and set up most of the plot parameters
plot(densCarrot, xlim = xlim, ylim = ylim, xlab = 'Lengths',
     main = 'Distribution of carrots and cucumbers', 
     panel.first = grid())
#put our density plots in
polygon(densCarrot, density = -1, col = carrotCol)
polygon(densCuke, density = -1, col = cukeCol)
## add a legend in the corner
legend('topleft',c('Carrots','Cucumbers'),
       fill = c(carrotCol, cukeCol), bty = 'n',
       border = NA)

এখানে চিত্র বর্ণনা লিখুন


9

@ ডর্ক এডেলবুয়েটেল: প্রাথমিক ধারণাটি দুর্দান্ত তবে প্রদর্শিত কোডটি উন্নত করা যেতে পারে। [ব্যাখ্যা করতে দীর্ঘ সময় নেয়, সুতরাং একটি পৃথক উত্তর এবং কোনও মন্তব্য নয়]]

hist()তাই আপনি যোগ করতে হবে ডিফল্টরূপে ফাংশন প্লটের স্বপক্ষে, plot=FALSEবিকল্প। তদ্ব্যতীত, plot(0,0,type="n",...)কলটি দিয়ে প্লট অঞ্চলটি স্থাপন করা আরও পরিষ্কার যা আপনি অক্ষ লেবেল যুক্ত করতে পারেন, প্লটের শিরোনাম ইত্যাদি Finally পরিশেষে, আমি উল্লেখ করতে চাই যে কেউ দুটি হিস্টোগ্রামের মধ্যে পার্থক্য করার জন্য শেড ব্যবহার করতে পারে। কোডটি এখানে:

set.seed(42)
p1 <- hist(rnorm(500,4),plot=FALSE)
p2 <- hist(rnorm(500,6),plot=FALSE)
plot(0,0,type="n",xlim=c(0,10),ylim=c(0,100),xlab="x",ylab="freq",main="Two histograms")
plot(p1,col="green",density=10,angle=135,add=TRUE)
plot(p2,col="blue",density=10,angle=45,add=TRUE)

এবং ফলাফলটি এখানে রয়েছে (আর স্টুডিওর কারণে কিছুটা প্রশস্ত :-)):

এখানে চিত্র বর্ণনা লিখুন


এটি আপিং কারণ এটি postscriptডিভাইসগুলিতে বেস এবং টেকসই ব্যবহার করে একটি খুব সহজ বিকল্প ।
মাইকেলচিরিকো

6

প্লটলি এর আর এপিআই আপনার জন্য দরকারী হতে পারে। নীচের গ্রাফটি এখানে

library(plotly)
#add username and key
p <- plotly(username="Username", key="API_KEY")
#generate data
x0 = rnorm(500)
x1 = rnorm(500)+1
#arrange your graph
data0 = list(x=x0,
         name = "Carrots",
         type='histogramx',
         opacity = 0.8)

data1 = list(x=x1,
         name = "Cukes",
         type='histogramx',
         opacity = 0.8)
#specify type as 'overlay'
layout <- list(barmode='overlay',
               plot_bgcolor = 'rgba(249,249,251,.85)')  
#format response, and use 'browseURL' to open graph tab in your browser.
response = p$plotly(data0, data1, kwargs=list(layout=layout))

url = response$url
filename = response$filename

browseURL(response$url)

সম্পূর্ণ প্রকাশ: আমি দলে আছি।

চিত্রলেখ


1

অনেক দুর্দান্ত উত্তর কিন্তু যেহেতু আমি কেবল একটি ফাংশন লিখেছি (plotMultipleHistograms() ) ফাংশন , তাই আমি ভেবেছিলাম যে আমি অন্য উত্তর যুক্ত করব।

এই ফাংশনের সুবিধাটি হ'ল এটি স্বয়ংক্রিয়ভাবে উপযুক্ত এক্স এবং ওয়াই অক্ষ সীমাটি সেট করে এবং বিনয়ের একটি সাধারণ সেট নির্ধারণ করে যা এটি সমস্ত বিতরণ জুড়ে ব্যবহার করে।

এটি কীভাবে ব্যবহার করবেন তা এখানে:

# Install the plotteR package
install.packages("devtools")
devtools::install_github("JosephCrispell/basicPlotteR")
library(basicPlotteR)

# Set the seed
set.seed(254534)

# Create random samples from a normal distribution
distributions <- list(rnorm(500, mean=5, sd=0.5), 
                      rnorm(500, mean=8, sd=5), 
                      rnorm(500, mean=20, sd=2))

# Plot overlapping histograms
plotMultipleHistograms(distributions, nBins=20, 
                       colours=c(rgb(1,0,0, 0.5), rgb(0,0,1, 0.5), rgb(0,1,0, 0.5)), 
                       las=1, main="Samples from normal distribution", xlab="Value")

এখানে চিত্র বর্ণনা লিখুন

plotMultipleHistograms()ফাংশন ডিস্ট্রিবিউশন যে কোন সংখ্যার নিতে পারেন, এবং সমস্ত সাধারণ ষড়যন্ত্র পরামিতি এটা দিয়ে কাজ করা উচিত (উদাহরণস্বরূপ: las, main, ইত্যাদি)।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.