Friday, 3 May 2019

Iterate and return contour value

I am trying to iterate and return the contour value gathered from a specific scatter point. The scatter point is taken from group C in the df below. I'm hoping to use this scatter point and return the normalised value within the contour for each frame.

The contour is generated from the code below. It's not relevant to the question but it essential in creating the animated scatter from group C (The value I want to return).

If I return print(normPDF[0,0]) I can return a normalised contour value but I'm hoping to apply this and to return for group C only.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scipy.stats as sts
import matplotlib.animation as animation
import matplotlib.transforms as transforms

DATA_LIMITS = [-85, 85]

def datalimits(*data):
    return DATA_LIMITS  # dmin - spad, dmax + spad

def mvpdf(x, y, xlim, ylim, radius=1, velocity=0, scale=0, theta=0):
    X,Y = np.meshgrid(np.linspace(*xlim), np.linspace(*ylim))
    XY = np.stack([X, Y], 2)
    PDF = sts.multivariate_normal([x, y]).pdf(XY)
    return X, Y, PDF

def mvpdfs(xs, ys, xlim, ylim, radius=None, velocity=None, scale=None, theta=None):
    PDFs = []
    for i,(x,y) in enumerate(zip(xs,ys)):
        X, Y, PDF = mvpdf(x, y, xlim, ylim)
        PDFs.append(PDF)

    return X, Y, np.sum(PDFs, axis=0)


''' Animate Plot '''

fig, ax = plt.subplots(figsize = (10,6))
ax.set_xlim(DATA_LIMITS)
ax.set_ylim(DATA_LIMITS)

line_a, = ax.plot([], [], '-o', c='red', alpha = 0.5, markersize=5,zorder=3)
line_b, = ax.plot([], [], '-o', c='blue', alpha = 0.5, markersize=5,zorder=3)
lines=[line_a,line_b] 

offset = lambda p: transforms.ScaledTranslation(p/82.,0, plt.gcf().dpi_scale_trans)
trans = plt.gca().transData

scat = ax.scatter([], [], s=5**2,marker='o', c='white', alpha = 0.5,zorder=3,transform=trans+offset(+2) )
scats=[scat] 

cfs = None

def plotmvs(tdf, xlim=None, ylim=None, fig=fig, ax=ax):    
    global cfs  
    if cfs:
        for tp in cfs.collections:
            tp.remove()

    df = tdf[1]

    if xlim is None: xlim = datalimits(df['X'])
    if ylim is None: ylim = datalimits(df['Y'])

    PDFs = []

    for (group, gdf), group_line in zip(df.groupby('group'), (line_a, line_b)):
        group_line.set_data(*gdf[['X','Y']].values.T)
        X, Y, PDF = mvpdfs(gdf['X'].values, gdf['Y'].values, xlim, ylim)
        PDFs.append(PDF)

    for (group, gdf), group_line in zip(df.groupby('group'), lines+scats):
            if group in ['A','B']:
                group_line.set_data(*gdf[['X','Y']].values.T)
                X, Y, PDF = mvpdfs(gdf['X'].values, gdf['Y'].values, xlim, ylim)
                PDFs.append(PDF)
            elif group in ['C']:
                gdf['X'].values, gdf['Y'].values
                scat.set_offsets(gdf[['X','Y']].values )

    normPDF = PDF - PDF.min()
    normPDF = normPDF / normPDF.max()

    cfs = ax.contourf(X, Y, normPDF, cmap='viridis', alpha = 1, levels=np.linspace(-1,1,10),zorder=1)

    print(normPDF[0,0])

    return  cfs.collections + [scat] + [line_a,line_b] 

n = 10
time = range(n)  

d = ({
    'A1_X' :    [13.3,13.16,12.99,12.9,12.79,12.56,12.32,12.15,11.93,11.72],
    'A1_Y' :    [26.12,26.44,26.81,27.18,27.48,27.82,28.13,28.37,28.63,28.93],
    'A2_X' :    [6.97,6.96,7.03,6.98,6.86,6.76,6.55,6.26,6.09,5.9],
    'A2_Y' :    [10.92,10.83,10.71,10.52,10.22,10.02,9.86,9.7,9.54,9.37],
    'B1_X' :    [38.35,38.1,37.78,37.55,37.36,37.02,36.78,36.46,36.21,35.79],
    'B1_Y' :    [12.55,12.58,12.58,12.55,12.5,12.47,12.43,12.48,12.44,12.44],
    'B2_X' :    [14.6,14.38,14.16,13.8,13.45,13.11,12.71,12.3,12.06,11.61],
    'B2_Y' :    [4.66,4.44,4.24,4.1,4.01,3.84,3.67,3.56,3.44,3.47],
    'C1_X' :    [10,15,18,20,30,33,35,42,34,20],
    'C1_Y' :    [10,16,20,10,20,13,15,12,14,10],
})

tuples = [((t, k.split('_')[0][0], int(k.split('_')[0][1:]), k.split('_')[1]), v[i])
    for k,v in d.items() for i,t in enumerate(time) ]

df = pd.Series(dict(tuples)).unstack(-1)
df.index.names = ['time', 'group', 'id']

interval_ms = 200
delay_ms = 1000
ani = animation.FuncAnimation(fig, plotmvs,  frames=df.groupby('time'), interval=interval_ms, repeat_delay=delay_ms,)

plt.show()



from Iterate and return contour value

1 comment:

  1. https://www.wizweb.in

    Wizweb Technology is a leading software development company custom website design, software development, SMS Provider, Bulk sms, transactional sms, promotional sms, mobile app development, Hosting Solution, seo(search engine optimization) and Digital marketing etc.

    ReplyDelete