Flaskを使ってみる

matplotlibのmarker機能


今回はmatplotlibのmarker機能を紹介します。
markerの詳細はこ ちらに公開されています。
markerに[s]や[v]などのマーク種類を指定すると以下の様にマーカを変えることができます。


markerには「(numsides, style, angle)」の指定方法が有ります。
numsidesとは画数のことで3ならば3角形、4ならば4角形のマークを表示します。
angleで角度を指定することができるので、以下の様にマークを傾けることができます。


markerには「verts」の指定方法が有ります。
vertsには[(-2, -4), (2, -4), (2, 4), (-2, 4)]の様に、(0, 0)を中心とした頂点の座標を指定します。
[(-2, -4), (2, -4), (2, 4), (-2, 4)]の場合、縦=2、横=4の長方形のマークが表示されます。

マークのサイズは正規化されるので、以下の指定はどちらも同じマークを表示します。
[(-1, -2), (1, -2), (1, 2), (-1, 2)]
[(-2, -4), (2, -4), (2, 4), (-2, 4)]

縦/横の比率を色々変えてみました。


「verts」の指定方法を使って、長方形のマークを回転させてみました。
任意の図形をマークとして使うことができます。




pytonコードは以下の通りです。
テンプレートは使っていません。
#!/usr/bin/python
#-*- encoding: utf-8 -*-
import math
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.backends.backend_agg import FigureCanvasAgg
import cStringIO
from flask import Flask, render_template, make_response

app = Flask(__name__)

@app.route("/graph11")
def graph11():
   fig, ax = matplotlib.pyplot.subplots()
   x = [0,10,20,30,40,50,60,70,80,90]
   for i in x:
       ax.scatter(i, i+00)
       ax.scatter(i, i+20, marker="s")
       ax.scatter(i, i+40, marker="v")
       ax.scatter(i, i+60, marker="*")

   canvas = FigureCanvasAgg(fig)
   buf = cStringIO.StringIO()
   canvas.print_png(buf)
   data = buf.getvalue()

   response = make_response(data)
   response.headers['Content-Type'] = 'image/png'
   response.headers['Content-Length'] = len(data)
   return response

@app.route("/graph12")
def graph12():
   fig, ax = matplotlib.pyplot.subplots()
   x = [0, 10,20,30,40,50,60,70,80,90]
   for i in x:
       ax.scatter(i, i+00, marker=(3, 0, i), s=100)
       ax.scatter(i, i+20, marker=(4, 0, 45+i), s=100)
       ax.scatter(i, i+40, marker=(5, 0, i), s=100)
       ax.scatter(i, i+60, marker=(6, 0, i), s=100)

   canvas = FigureCanvasAgg(fig)
   buf = cStringIO.StringIO()
   canvas.print_png(buf)
   data = buf.getvalue()

   response = make_response(data)
   response.headers['Content-Type'] = 'image/png'
   response.headers['Content-Length'] = len(data)
   return response

def verts_function(x,y,r1,r2):
    # Define the vertex's multiplying the x value by a ratio
    x = x*r1
    y = y*r2
    print [(-x,-y),(x,-y),(x,y),(-x,y)]
    return [(-x,-y),(x,-y),(x,y),(-x,y)]

@app.route("/graph13")
def graph13():
   fig, ax = matplotlib.pyplot.subplots()
   x = [0,10,20,30,40,50,60,70,80,90]
   r=0
   for i in x:
       r=r+0.1
       ax.scatter(i, i, marker=(verts_function(4,4,1,r),0),s=200)
       ax.scatter(i, i+20, marker=(verts_function(4,4,r,1),0),s=200)

   canvas = FigureCanvasAgg(fig)
   buf = cStringIO.StringIO()
   canvas.print_png(buf)
   data = buf.getvalue()

   response = make_response(data)
   response.headers['Content-Type'] = 'image/png'
   response.headers['Content-Length'] = len(data)
   return response

# https://matplotlib.org/3.1.1/api/markers_api.html#module-matplotlib.markers
# https://stackoverflow.com/questions/16189928/understanding-matplotlib-verts
# https://keisan.casio.jp/exec/system/1496883774
#
def vert_calc0(rad, l):
    pi=math.pi
    #print "rad=",rad, " l=",l
    t=math.radians(rad)
    x1=math.cos(t)*l/2
    y1=math.sin(t)*l/2
    #print "x1=",x1,"y1=",y1

    x2=math.cos(pi-t)*l/2
    y2=math.sin(pi-t)*l/2
    #print "x2=",x2,"y2=",y2

    x3=math.cos(pi+t)*l/2
    y3=math.sin(pi+t)*l/2
    #print "x3=",x3,"y3=",y3

    x4=math.cos(-t)*l/2
    y4=math.sin(-t)*l/2
    #print "x4=",x4,"y4=",y4

    #print list(zip([x3,x4,x1,x2],[y3,y4,y1,y2]))
    return list(zip([x3,x4,x1,x2],[y3,y4,y1,y2]))

def vert_rotation(x,y,rot):
    t1=math.radians(rot)
    x1=x*math.cos(t1)-y*math.sin(t1)
    y1=x*math.sin(t1)+y*math.cos(t1)
    return x1,y1

def vert_calc1(rad,l,rot):
    pi=math.pi
    #print "rad=",rad, " l=",l
    t=math.radians(rad)
    #t1=math.radians(rot)
    x=math.cos(t)*l/2
    y=math.sin(t)*l/2
    x1,y1=vert_rotation(x,y,rot)
    #print "x1*=",x1,"y1*=",y1

    x=math.cos(pi-t)*l/2
    y=math.sin(pi-t)*l/2
    x2,y2=vert_rotation(x,y,rot)
    #print "x2=",x2,"y2=",y2

    x=math.cos(pi+t)*l/2
    y=math.sin(pi+t)*l/2
    x3,y3=vert_rotation(x,y,rot)
    #print "x3=",x3,"y3=",y3

    x=math.cos(-t)*l/2
    y=math.sin(-t)*l/2
    x4,y4=vert_rotation(x,y,rot)
    #print "x4=",x4,"y4=",y4

    return list(zip([x3,x4,x1,x2],[y3,y4,y1,y2]))

@app.route("/graph14")
def graph14():
   fig, ax = matplotlib.pyplot.subplots()
   x = [10,20,30,40,50,60,70,80]
   #v_val=1.0
   #h_val=2.0
   #verts = list(zip([-h_val,h_val,h_val,-h_val],[-v_val,-v_val,v_val,v_val]))
   #verts = [(-2.0, -1.0), (2.0, -1.0), (2.0, 1.0), (-2.0, 1.0)]
   for i in x:
       verts = vert_calc1(i,4,0)
       print verts
       ax.scatter(i, i, marker=(verts,0), s=200)

   canvas = FigureCanvasAgg(fig)
   buf = cStringIO.StringIO()
   canvas.print_png(buf)
   data = buf.getvalue()

   response = make_response(data)
   response.headers['Content-Type'] = 'image/png'
   response.headers['Content-Length'] = len(data)
   return response


@app.route("/graph15")
def graph15():
   fig, ax = matplotlib.pyplot.subplots()
   x = [0,10,20,30,40,50,60,70,80,90]
   #v_val=1.0
   #h_val=2.0
   #verts = list(zip([-h_val,h_val,h_val,-h_val],[-v_val,-v_val,v_val,v_val]))
   #verts = [(-2.0, -1.0), (2.0, -1.0), (2.0, 1.0), (-2.0, 1.0)]
   for i in x:
       verts = vert_calc1(40,4,i)
       print verts
       ax.scatter(i, i, marker=(verts,0), s=200)

   canvas = FigureCanvasAgg(fig)
   buf = cStringIO.StringIO()
   canvas.print_png(buf)
   data = buf.getvalue()

   response = make_response(data)
   response.headers['Content-Type'] = 'image/png'
   response.headers['Content-Length'] = len(data)
   return response


if __name__ == "__main__":
   app.run(host='0.0.0.0', port=80, debug=True)

続く...