How to run OpenAI Gym .render() over a server How to run OpenAI Gym .render() over a server python python

How to run OpenAI Gym .render() over a server


Got a simple solution working:

CartPole

If on a linux server, open jupyter with
$ xvfb-run -s "-screen 0 1400x900x24" jupyter notebook
In Jupyter
import matplotlib.pyplot as plt%matplotlib inlinefrom IPython import display
After each step
def show_state(env, step=0, info=""):    plt.figure(3)    plt.clf()    plt.imshow(env.render(mode='rgb_array'))    plt.title("%s | Step: %d %s" % (env._spec.id,step, info))    plt.axis('off')    display.clear_output(wait=True)    display.display(plt.gcf())

Note: if your environment is not unwrapped, pass env.env to show_state.


This GitHub issue gave an answer that worked great for me. It's nice because it doesn't require any additional dependencies (I assume you already have matplotlib) or configuration of the server.

Just run, e.g.:

import gymimport matplotlib.pyplot as plt%matplotlib inlineenv = gym.make('Breakout-v0') # insert your favorite environmentrender = lambda : plt.imshow(env.render(mode='rgb_array'))env.reset()render()

Using mode='rgb_array' gives you back a numpy.ndarray with the RGB values for each position, and matplotlib's imshow (or other methods) displays these nicely.

Note that if you're rendering multiple times in the same cell, this solution will plot a separate image each time. This is probably not what you want. I'll try to update this if I figure out a good workaround for that.

Update to render multiple times in one cell

Based on this StackOverflow answer, here's a working snippet (note that there may be more efficient ways to do this with an interactive plot; this way seems a little laggy on my machine):

import gymfrom IPython import displayimport matplotlib.pyplot as plt%matplotlib inlineenv = gym.make('Breakout-v0')env.reset()for _ in range(100):    plt.imshow(env.render(mode='rgb_array'))    display.display(plt.gcf())    display.clear_output(wait=True)    action = env.action_space.sample()    env.step(action)

Update to increase efficiency

On my machine, this was about 3x faster. The difference is that instead of calling imshow each time we render, we just change the RGB data on the original plot.

import gymfrom IPython import displayimport matplotlibimport matplotlib.pyplot as plt%matplotlib inlineenv = gym.make('Breakout-v0')env.reset()img = plt.imshow(env.render(mode='rgb_array')) # only call this oncefor _ in range(100):    img.set_data(env.render(mode='rgb_array')) # just update the data    display.display(plt.gcf())    display.clear_output(wait=True)    action = env.action_space.sample()    env.step(action)


I managed to run and render openai/gym (even with mujoco) remotely on a headless server.

# Install and configure X window with virtual screensudo apt-get install xserver-xorg libglu1-mesa-dev freeglut3-dev mesa-common-dev libxmu-dev libxi-dev# Configure the nvidia-xsudo nvidia-xconfig -a --use-display-device=None --virtual=1280x1024# Run the virtual screen in the background (:0)sudo /usr/bin/X :0 &# We only need to setup the virtual screen once# Run the program with vitural screenDISPLAY=:0 <program># If you dont want to type `DISPLAY=:0` everytimeexport DISPLAY=:0

Usage:

DISPLAY=:0 ipython2

Example:

import gymenv = gym.make('Ant-v1')arr = env.render(mode='rgb_array')print(arr.shape)# plot or save wherever you want# plt.imshow(arr) or scipy.misc.imsave('sample.png', arr)