将条形图的列与ggplot的线图对齐

时间:2015-05-24 16:45:28

标签: r ggplot2

当它们具有相同的x轴时,是否有任何方法可以使用ggplot将线图的点与条形图的条形对齐?以下是我尝试使用的示例数据。

library(ggplot2)
library(gridExtra)

data=data.frame(x=rep(1:27, each=5), y = rep(1:5, times = 27))
yes <- ggplot(data, aes(x = x, y = y))
yes <- yes + geom_point() + geom_line()

other_data = data.frame(x = 1:27, y = 50:76  )

no <- ggplot(other_data, aes(x=x, y=y))
no <- no + geom_bar(stat = "identity")

grid.arrange(no, yes)

这是输出:

enter image description here

线图的第一个点位于第一个柱的左侧,线图的最后一个点位于最后一个柱的右侧。

感谢您的时间。

2 个答案:

答案 0 :(得分:2)

稍微扩展@ Stibu的帖子:要对齐图表,请使用gtable(或查看your earlier question的答案)

library(ggplot2)
library(gtable)

data=data.frame(x=rep(1:27, each=5), y = rep(1:5, times = 27))
yes <- ggplot(data, aes(x = x, y = y))
yes <- yes + geom_point() + geom_line() + 
   scale_x_continuous(limits = c(0,28), expand = c(0,0))

other_data = data.frame(x = 1:27, y = 50:76  )

no <- ggplot(other_data, aes(x=x, y=y))
no <- no + geom_bar(stat = "identity") + 
   scale_x_continuous(limits = c(0,28), expand = c(0,0))

gYes = ggplotGrob(yes)   # get the ggplot grobs
gNo = ggplotGrob(no)

plot(rbind(gNo, gYes, size = "first"))   # Arrange and plot the grobs

enter image description here

修改要更改地块的高度:

g = rbind(gNo, gYes, size = "first")  # Combine the plots
panels <- g$layout$t[grepl("panel", g$layout$name)] # Get the positions for plot panels
g$heights[panels] <- unit(c(0.7, 0.3), "null") # Replace heights with your relative heights
plot(g)

答案 1 :(得分:1)

我可以想到(至少)两种方法来对齐两个图中的x轴:

  1. 两个轴不对齐,因为在条形图中,geom覆盖x轴从0.5到27.5,而在另一个图中,数据的范围从1到27.原因是酒吧有一个宽度,点不要。您可以通过显式指定x轴范围来强制axex对齐。使用图中的定义,可以通过

    实现
    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    import re
    import csv
    from time import sleep
    from itertools import *
    
    # Omitted code here, navigates to search form on web page.
    
    with open("file1.csv", "rb+a") as file1_read: # Open file1.csv containing column with searchkey (id).
        r = csv.reader(file1_read, delimiter = ",")
        for id in r:
            searchkey = driver.find_element_by_name("searchkey")
            searchkey.clear()
            searchkey.send_keys(id)
            print "\nSearching for %s ..." % id
            sleep(9) # Sleep timer, allow for retrieving results
            search_reply = driver.find_element_by_class_name("ac_results") # Get list, variable how many items and what their contents may be. Price and product names are extracted through regex.
            price = re.findall("((?<=\()[0-9]*)", search_reply.text)
            product_name = re.findall("(.*?)\(", search_reply.text)
            with open("file2.csv", "a") as file2_write: # Write to file2.csv.
                    wr = csv.writer(file2_write, delimiter = ",")
                    wr.writerow(id)
                    wr.writerow(product_name)
                    wr.writerow(price)
    
    driver.quit()
    

    yes <- yes + scale_x_continuous(limits=c(0,28)) no <- no + scale_x_continuous(limits=c(0,28)) grid.arrange(no, yes) 设置x轴的范围。但请注意,藻酸盐仍不完美。 y轴标签在上图中占用更多空间,因为数字有两位数。情节如下: enter image description here

  2. 另一个解决方案有点复杂,但它的优点是x轴只绘制一次,而ggplot确保对齐是完美的。它利用了this answer中描述的分面和技巧。首先,必须通过

    将数据合并为一个数据框
    limits

    然后可以按如下方式创建绘图:

    all <- rbind(data.frame(other_data,type="other"),data.frame(data,type="data"))
    

    诀窍是让facet由之前用过的变量ggplot(all,aes(x=x,y=y)) + facet_grid(type~.,scales = "free_y") + geom_bar(data=subset(all,type=="other"),stat="identity") + geom_point(data=subset(all,type=="data")) + geom_line(data=subset(all,type=="data")) 构造,以标记两个数据集。但是,每个type只获取应该使用该特定geom绘制的数据子集。在geom中,我还使用了facet_grid,因为两个y轴应该是独立的。该图如下:

  3. enter image description here

    您可以在定义数据框scales = "free_y"时通过提供其他名称来更改构面的标签。如果要将它们全部删除,请将以下内容添加到绘图中:

    all