如何在ggplot2 R中使用sec_axis()表示离散数据?

时间:2017-09-04 23:55:50

标签: r ggplot2 axes multiple-axes

我有谨慎的数据,如下所示:

height <- c(1,2,3,4,5,6,7,8)
weight <- c(100,200,300,400,500,600,700,800)
person <- c("Jack","Jim","Jill","Tess","Jack","Jim","Jill","Tess")
set <- c(1,1,1,1,2,2,2,2)
dat <- data.frame(set,person,height,weight)

我正在尝试绘制具有相同x轴(人物)和2个不同y轴(重量和高度)的图表。我发现所有的例子都试图用基础图来绘制secondary axis (sec_axis)或谨慎的数据。 是否有一种简单的方法可以将sec_axis用于ggplot2上的谨慎数据? 编辑:评论中的某人建议我尝试建议的回复。但是,我现在遇到这个错误

这是我目前的代码:

p1 <- ggplot(data = dat, aes(x = person, y = weight)) + 
  geom_point(color = "red") + facet_wrap(~set, scales="free") 
p2 <- p1 + scale_y_continuous("height",sec_axis(~.*1.2, name="height"))
p2

I get the error: Error in x < range[1] : 
  comparison (3) is possible only for atomic and list types

或者,现在我修改了示例以匹配this example posted.

p <- ggplot(dat, aes(x = person))
p <- p + geom_line(aes(y = height, colour = "Height"))

# adding the relative weight data, transformed to match roughly the range of the height
p <- p + geom_line(aes(y = weight/100, colour = "Weight"))

# now adding the secondary axis, following the example in the help file ?scale_y_continuous
# and, very important, reverting the above transformation
p <- p + scale_y_continuous(sec.axis = sec_axis(~.*100, name = "Relative weight [%]"))

# modifying colours and theme options
p <- p + scale_colour_manual(values = c("blue", "red"))
p <- p + labs(y = "Height [inches]",
              x = "Person",
              colour = "Parameter")
p <- p + theme(legend.position = c(0.8, 0.9))+ facet_wrap(~set, scales="free") 
p

我收到错误消息

"geom_path: Each group consists of only one observation. Do you need to 
 adjust the group aesthetic?"

我得到了模板,但没有绘制点

1 个答案:

答案 0 :(得分:0)

如果未明确指定参数名称,则按位置输入R函数参数。正如@ Z.Lin在评论中所提到的,在import socketio import imp import json from datetime import datetime, timedelta gameDBModule = imp.load_compiled("ChatDatabase", "./game_chat/chat_database.pyc") apiModule = imp.load_compiled("TotoAPI", "./game_api/__init__.pyc") class GameChat(socketio.Namespace): def init(self): self.lastDataIndex = 0 self.api = apiModule.TotoAPI() def on_join(self, sid, message): self.db = gameDBModule.ChatDatabase() sessid = self.getUserId(sid) try: info = json.loads(self.api.userinfo(sessid)) userID = str(info[4]) except Exception as e: userID = None self.emit('join', {'history': self.db.get_chathistory(), 'channel': message, 'moderator': False, 'user_id': userID}, room=sid) def on_connect(self, sid, environ): self.emit('connect', {'data': 'Connected', 'count': 0}, room=sid) print('GameChat Connected') def on_say(self, sid, message, environ): sessid =self.getUserId(sid) try: info = json.loads(self.api.userinfo(sessid)) userID = str(info[4]) except Exception as e: userID = None if userID !=None: userID = None #Save into History now = self.get_current_time(9) self.lastDataIndex = self.lastDataIndex + 1 item = { 'dataIndex': self.lastDataIndex, 'bot': False, 'date': now, 'message': message, 'role': 'user', 'type': 'say', 'user_id': userID } self.emit('msg', item) item['date'] = self.get_current_time(0) self.db.insert_chatting(item) def on_disconnect(self, sid): print('GameChat disconnected') def getUserId(self, sid): try: #Get UserID from Cookies cookies = str(self.server.environ[sid]['HTTP_COOKIE']).split(';') id = None for item in (cookies): name=str(item).split('=')[0].strip() value=str(item).split('=')[1].strip() if name.__eq__('ci_session'): id = value return id except Exception as e: return None def get_current_time(self, diff): i = datetime.now() - timedelta(hours = diff) return i.isoformat()[:-3]+"Z" this is the code using above name space async_mode = 'eventlet' import eventlet import eventlet.wsgi from flask import Flask, render_template, Response, request, make_response import socketio import imp gameChatModule = imp.load_compiled("GameChat", "./game_chat/__init__.pyc") apiModule = imp.load_compiled("TotoAPI", "./game_api/__init__.pyc") sio = socketio.Server(logger=False, async_mode=async_mode) app = Flask(__name__) app.wsgi_app = socketio.Middleware(sio, app.wsgi_app) app.config['SECRET_KEY'] = 'secret!' api = apiModule.TotoAPI() ns = gameChatModule.GameChat("/") ns.init() if __name__ == '__main__': sio.register_namespace(ns) eventlet.wsgi.server(eventlet.listen(('', 8880)), app) 函数之前需要sec.axis=来表明您正在将此函数提供给sec_axis sec.axis的{​​{1}}参数。如果您不这样做,它将被输入scale_y_continuous的第二个参数,默认情况下为scale_y_continuous。因此,错误消息与您没有为breaks=参数提供可接受的数据类型有关:

breaks

![enter image description here

p1 <- ggplot(data = dat, aes(x = person, y = weight)) + geom_point(color = "red") + facet_wrap(~set, scales="free") p2 <- p1 + scale_y_continuous("weight", sec.axis = sec_axis(~.*1.2, name="height")) p2 的第一个参数(name=)用于第一个 y比例,其中scale_y_continuous参数用于第二个< / em> y scale。我更改了你的第一个y刻度名称来纠正它。