xgadam
xgadam

Reputation: 180

How to get matplotlib graphs to display on OS X from script running in docker container

As the title states, I have a docker container, using the ubuntu 16.04 base image, with matplotlib and various dependencies installed.

I know I could use a jupyter notebook or something else to write the plot to a file or something, however I specifically want to be able to drop into a python shell within the container and call plt.plot() from there.

I have read about setting display variables and the like but so far have not had much luck.

Any help would be appreciated.

Upvotes: 6

Views: 1115

Answers (2)

ascendants
ascendants

Reputation: 2381

Based on the original question's setup with an Ubuntu container and Python3/Matplotlib installed*, you won't need jupyter or notebooks to save the figure. But, you will have to run the container with a mounted volume using -v.

Here's an example for how to directly enter the Python terminal in the container and run plt.plot(). You can then save the figure to the mounted volume and display that figure on the host machine:

docker run -it --name ubuntu_python -v /output/:/output/ <your_ubuntu_image> /bin/bash

This will put you inside the container with a bash terminal, from which you can install dependencies, run python3, etc. If you want to access the container (with its same mounted volumes) after exiting, you can always use (as @ssnk mentioned):

docker exec -it ubuntu_python /bin/bash

After running python3 (or python) in the container, you will have a python shell from which you can generate and save your figure to the mounted volume /output:

import matplotlib.pyplot as plt

x = list(range(1,10))
y = list(range(1,10))

fig1 = plt.figure()
plt.plot(x,y)

# increase your pixel density when saving the image
# (optional, but it's useful when you can't inspect the image beforehand with plt.show)
your_dpi = 200  

out_path = '/output/your_filename.png'

plt.savefig(out_path, dpi=your_dpi)

You can then view the file on the host machine as /output/your_filename.png. Without using display variables with Docker, this is a reliable method to view a figure created inside a container (for interactivity, you could try jupyter).


*An aside: if you don't want to manually install the dependencies each time you start the container (such as if you need to mount a new volume), here's a quick example that creates a Docker container with your dependencies pre-installed using conda:

Create Dockerfile.conda and entrypoint.sh as follows:

# Dockerfile.conda

FROM ubuntu:bionic

RUN apt-get update -y \
    && apt upgrade -y \
    && apt install -y wget

RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh \
    && mkdir /root/.conda \
    && bash Miniconda3-latest-Linux-x86_64.sh -b \
    && rm -f Miniconda3-latest-Linux-x86_64.sh

ENV PATH /root/miniconda3/bin:$PATH

### Add your packages here ###
RUN conda install -y matplotlib

# Set up runtime

COPY entrypoint.sh /entrypoint.sh
RUN chmod 755 /entrypoint.sh

ENTRYPOINT ["/bin/bash", "entrypoint.sh"]
# entrypoint.sh

#!/bin/sh                                                                                            
conda init bash
/bin/bash    #refresh the shell to load conda
conda activate base

Build the image by running this in the same directory:

docker build . -t username/ubuntu:conda -f Dockerfile.conda

You can now run your matplotlib Python container by naming the image username/ubuntu:conda instead of installing each time in a shell.

Upvotes: 1

ssnk
ssnk

Reputation: 36

From what I understand you want to run a command in python shell that is running inside docker.

If that is correct you can run your container and then simply do this

docker exec -it CONTAINER_NAME python

Note python can be python3 depending on your container.

this will connect you to the python shell inside container. Then you can do your magic.

Additionally if you want to generate graphs to files, you can write them to a folder that is mounted from host, so you get your outputs in your OSX machine.

Hope this helps.

Upvotes: 0

Related Questions