Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 930
xgadam Avatar asked Jun 11 '18 12:06

xgadam


People also ask

Why isn't my plot showing in Python?

It means if we are not using the show() function, it wouldn't show any plot. When we use the show() function in the non-interactive mode. That means when we write the code in the file it will show all the figures or plots and blocks until the plots have been closed.

Why is matplotlib not working?

Matplotlib is not a built-in module (it doesn't come with the default python installation) in Python, you need to install it explicitly using the pip installer and then use it. If you looking at how to install pip or if you are getting an error installing pip checkout pip: command not found to resolve the issue.

Why is %Matplotlib inline?

Why matplotlib inline is used. You can use the magic function %matplotlib inline to enable the inline plotting, where the plots/graphs will be displayed just below the cell where your plotting commands are written. It provides interactivity with the backend in the frontends like the jupyter notebook.


1 Answers

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.

like image 119
ascendants Avatar answered Sep 29 '22 02:09

ascendants