Skip to content

Matplotlib

Provides a MATLAB-like plotting framework.

matplotlib is a plotting library for the Python programming language and its numerical mathematics extension NumPy. It provides an object-oriented API for embedding plots into applications using general-purpose GUI toolkits like wxPython, Qt, or GTK+. There is also a procedural "pylab" interface based on a state machine (like OpenGL), designed to closely resemble that of MATLAB. SciPy makes use of matplotlib.

Categories

How to install

OSX pyenv-virtualenv - matplotlib

Simple example

import matplotlib.pyplot as plt
plt.plot([1,2,3,4], [1,2,3,4])
plt.show()

Use the Numpy version:

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 5, 0.1);
y = np.sin(x)
plt.plot(x, y)
# plt.show()

With Jupyter widgets:

from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets
import matplotlib.pyplot as plt

@interact(y=1.0)
def g(y):
    plt.plot([1,2,3,4], [1,2,3,y])
    plt.show()
    pass

Draw points

import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4, 5], [1, 2, 1.3, 3.75, 2.25], 'ro')
plt.axis([0, 6, 0, 6])
plt.show()

Timer event handling

# Simple example of using general timer objects. This is used to update
# the time placed in the title of the figure.
import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime


def update_title(axes):
    axes.set_title(datetime.now())
    axes.figure.canvas.draw()

fig, ax = plt.subplots()

x = np.linspace(-3, 3)
ax.plot(x, x*x)

# Create a new timer object. Set the interval to 100 milliseconds
# (1000 is default) and tell the timer what function should be called.
timer = fig.canvas.new_timer(interval=100)
timer.add_callback(update_title, ax)
timer.start()

# Or could start the timer on first figure draw
#def start_timer(evt):
#    timer.start()
#    fig.canvas.mpl_disconnect(drawid)
#drawid = fig.canvas.mpl_connect('draw_event', start_timer)

plt.show()

Other timer example

import numpy as np
import matplotlib.pyplot as plt

def on_timer(line, x, y):
    x.append(x[-1] + np.random.normal(0, 1))
    y.append(y[-1] + np.random.normal(0, 1))
    line.set_data(x, y)
    line.axes.relim()
    line.axes.autoscale_view()
    line.axes.figure.canvas.draw()

x, y = [np.random.normal(0, 1)], [np.random.normal(0, 1)]
fig, ax = plt.subplots()
line, = ax.plot(x, y, color='aqua', marker='o')

timer = fig.canvas.new_timer(interval=100, 
                             callbacks=[(on_timer, [line, x, y], {})])
timer.start()

plt.show()

mplot3d

An Axes3D object is created just like any other axes using the projection=‘3d’ keyword. Create a new matplotlib.figure.Figure and add a new axes to it of type Axes3D:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

Mergin

subplots_adjust함수를 사용하면 된다. 0~1의 비율 값을 사용하면 된다. 그리고 해당 값은 마진 크기가 아닌 위치(Position) 값의 비율이다.

import matplotlib.pyplot as plt
plt.plot(whatever)
plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1)

matplotlib with opencv imshow example

방법은, figurenumpy.array로 변환하는 것 이다.

import matplotlib
matplotlib.use('TkAgg')

import numpy as np
import cv2
import matplotlib.pyplot as plt

fig = plt.figure()
cap = cv2.VideoCapture(0)


x1 = np.linspace(0.0, 5.0)
x2 = np.linspace(0.0, 2.0)

y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
y2 = np.cos(2 * np.pi * x2)


line1, = plt.plot(x1, y1, 'ko-')        # so that we can update data later

for i in range(1000):
    # update data
    line1.set_ydata(np.cos(2 * np.pi * (x1+i*3.14/2) ) * np.exp(-x1) )

    # redraw the canvas
    fig.canvas.draw()

    # convert canvas to image
    img = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8,
            sep='')
    img  = img.reshape(fig.canvas.get_width_height()[::-1] + (3,))

    # img is rgb, convert to opencv's default bgr
    img = cv2.cvtColor(img,cv2.COLOR_RGB2BGR)


    # display image with opencv or any operation you like
    cv2.imshow("plot",img)

    # display camera feed
    ret,frame = cap.read()
    cv2.imshow("cam",frame)

    k = cv2.waitKey(33) & 0xFF
    if k == 27:
        break

Benchmark figure to numpy array

import io
import matplotlib
matplotlib.use('agg')  # turn off interactive backend
import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
ax.plot(range(10))


def plot1():
    fig.canvas.draw()
    data = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)
    w, h = fig.canvas.get_width_height()
    im = data.reshape((int(h), int(w), -1))


def plot2():
    with io.BytesIO() as buff:
        fig.savefig(buff, format='png')
        buff.seek(0)
        im = plt.imread(buff)


def plot3():
    with io.BytesIO() as buff:
        fig.savefig(buff, format='raw')
        buff.seek(0)
        data = np.frombuffer(buff.getvalue(), dtype=np.uint8)
    w, h = fig.canvas.get_width_height()
    im = data.reshape((int(h), int(w), -1))

Result:

>>> %timeit plot1()
34 ms ± 4.16 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
>>> %timeit plot2()
50.2 ms ± 234 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
>>> %timeit plot3()
16.4 ms ± 36 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Additional way

이런 방법도 있다:

# Figure to np.array 
# https://matplotlib.org/gallery/misc/agg_buffer_to_array.html
import numpy as np 
import matplotlib.pyplot as plt 

def figure_to_array(fig):
    """
    plt.figure를 RGBA로 변환(layer가 4개)
    shape: height, width, layer
    """
    fig.canvas.draw()
    return np.array(fig.canvas.renderer._renderer)

f = plt.figure()
s = 10000
plt.scatter(np.random.normal(0, 1, s), np.random.normal(0, 1, s), alpha=0.5)
#plt.margins(0, 0, tight=False)
plt.close() # 쥬피터 노트북에 그림이 자동으로 뜨는 것을 막으려고 사용. 

f_arr = figure_to_array(f)
print(f_arr.shape) # 이 RGBA로 변환됨. 
plt.figure()
plt.imshow(f_arr[:, :, :])
#plt.margins(0, 0, tight=False)
plt.savefig('../../assets/images/markdown_img/180629_figure_to_nparray.svg')
plt.show()

matplotlib with wxPython example

import argparse

from numpy import arange, sin, pi
import matplotlib
matplotlib.use('WXAgg')

from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure

import wx

class CanvasPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.slider = wx.Slider(self, -1, value=1, minValue=0, maxValue=11)
        self.slider.Bind(wx.EVT_SLIDER, self.OnSlider)
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, proportion=1, 
                        flag=wx.LEFT | wx.TOP | wx.GROW)
        self.sizer.Add(self.slider, proportion=0, 
                        flag=wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()

    def OnSlider(self, event):
        self.draw()

    def draw(self):
        t = arange(0.0, 3.0, 0.01)
        h = self.slider.GetValue()
        s = h * sin(2*pi*t)
        self.axes.clear()
        self.axes.plot(t, s)
        self.canvas.draw()


if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = wx.Frame(None, title='test')
    panel = CanvasPanel(frame)
    panel.draw()
    frame.Show()
    app.MainLoop()

Headless Mode

import matplotlib
matplotlib.use('Agg')

See also

Favorite site

Visualizing

References


  1. Introduction_to_visualization_package_matplotlib.pdf 

  2. Visualizing_the_gradient_descent_method.pdf