22

I want to play with the OpenAI gyms in a notebook, with the gym being rendered inline.

Here's a basic example:

import matplotlib.pyplot as plt
import gym
from IPython import display
%matplotlib inline

env = gym.make('CartPole-v0')
env.reset()

for i in range(25):
   plt.imshow(env.render(mode='rgb_array'))
   display.display(plt.gcf())    
   display.clear_output(wait=True)
   env.step(env.action_space.sample()) # take a random action

env.close()

This works, and I get see the gym in the notebook:

gym in notebook

But! it also opens an interactive window that shows precisely the same thing. I don't want this window to be open:

interactive window

MasterScrat
  • 7,090
  • 14
  • 48
  • 80

3 Answers3

17

I made a working example here that you can fork: https://kyso.io/eoin/openai-gym-jupyter with two examples of rendering in Jupyter - one as an mp4, and another as a realtime gif.

The .mp4 example is quite simple.

import gym
from gym import wrappers

env = gym.make('SpaceInvaders-v0')
env = wrappers.Monitor(env, "./gym-results", force=True)
env.reset()
for _ in range(1000):
    action = env.action_space.sample()
    observation, reward, done, info = env.step(action)
    if done: break
env.close()

Then in a new cell

import io
import base64
from IPython.display import HTML

video = io.open('./gym-results/openaigym.video.%s.video000000.mp4' % env.file_infix, 'r+b').read()
encoded = base64.b64encode(video)
HTML(data='''
    <video width="360" height="auto" alt="test" controls><source src="data:video/mp4;base64,{0}" type="video/mp4" /></video>'''
.format(encoded.decode('ascii')))
Eoin Murray
  • 1,935
  • 3
  • 22
  • 34
  • 7
    This doesn't work for me. Did you try with `CartPole-v0`? The window still opens for me. This problem doesn't occur with `SpaceInvaders-v0`, but that's not environment I want to use, so this is not relevant. – MasterScrat Aug 07 '19 at 11:10
8

I just found a pretty nice work-around for this. This will work for environments that support the rgb_array render mode. Then we can use matplotlib's imshow with a quick replacement to show the animation. The following should work inside one cell of a jupyter notebook.

import os
import gym
import matplotlib.pyplot as plt
os.environ["SDL_VIDEODRIVER"] = "dummy"
from IPython.display import clear_output

env = gym.make("LunarLander-v2")#, render_mode="human")
env.action_space.seed(42)

observation, info = env.reset(seed=42, return_info=True)

for _ in range(1000):
    observation, reward, done, info = env.step(env.action_space.sample())

    if done:
        observation, info = env.reset(return_info=True)
        
    clear_output(wait=True)
    plt.imshow( env.render(mode='rgb_array') )
    plt.show()

env.close()
jeffery_the_wind
  • 17,048
  • 34
  • 98
  • 160
3

This worked for me in Ubuntu 18.04 LTS, to render gym locally. But, I believe it will work even in remote Jupyter Notebook servers.

First, run the following installations in Terminal:

pip install gym
python -m pip install pyvirtualdisplay
pip3 install box2d
sudo apt-get install xvfb

That's just it. Use the following snippet to configure how your matplotlib should render :

import matplotlib.pyplot as plt
from pyvirtualdisplay import Display
display = Display(visible=0, size=(1400, 900))
display.start()

is_ipython = 'inline' in plt.get_backend()
if is_ipython:
    from IPython import display

plt.ion()

# Load the gym environment

import gym
import matplotlib.pyplot as plt
%matplotlib inline

env = gym.make('LunarLander-v2')
env.seed(23)

# Let's watch how an untrained agent moves around

state = env.reset()
img = plt.imshow(env.render(mode='rgb_array'))
for j in range(200):
#     action = agent.act(state)
    action = random.choice(range(4))
    img.set_data(env.render(mode='rgb_array')) 
    plt.axis('off')
    display.display(plt.gcf())
    display.clear_output(wait=True)
    state, reward, done, _ = env.step(action)
    if done:
        break 
        
env.close()
bad programmer
  • 818
  • 7
  • 12
  • Any significance to the three different ways to invoke pip? (pip, python -m pip, pip3) – 4Oh4 May 05 '22 at 13:58