Damien Rompapas
Damien Rompapas

Reputation: 21

Formatting data for use in Streamplot

I'm having a little trouble, mostly because it's a little hard for me to wrap into python world for matplotlib.

I have 4 1D arrays as follows:

x -> x positions
y -> y positions
u -> x velocities
v -> y velocities

Which I've described in python variables as follows (these are populated by the data I'm reading which is irrelevant, each 1D array is equal in length)

x_points : List[float] = []
y_points : List[float] = []
x_vel : List[float] = []
y_vel : List[float] = []

And I'm having a hard time transferring these 1D arrays into a format that can be used to plot a streamline graph. (I'm trying to follow the answer from this question here but am still scratching my head) Currently my code looks like this (I've omitted the data population)

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np
import pandas as pd
x_points : List[float] = []
y_points : List[float] = []
x_vel : List[float] = []
y_vel : List[float] = []
#Data Population
#End Data Population
xi = np.linspace(-20, 20, len(x_points))
yi = np.linspace(-20, 20, len(z_points))
X, Y = np.meshgrid(xi, yi)
U = interpolate.griddata((x_points, y_points), x_vel, (X, Y), method='cubic')
V = interpolate.griddata((x_points, y_points), y_vel, (X, Y), method='cubic')
f, ax = plt.subplots(figsize=(6,6))
ax.streamplot(X,Y,U,V, density=[0.2,1])

which I'm already aware will not work.

Could I have some help describing how I should transform the 4 1D arrays into something that streamplot is happy with?

Upvotes: 2

Views: 637

Answers (2)

Damien Rompapas
Damien Rompapas

Reputation: 21

The problem was that python was giving me a series of errors relating to a mismatch in array sizes.

I've figured it out, it turns out I was quite close, and the answer was quite simple, but I'm getting some rather strange results.

First the answer: when calling np.linspace, I need to use the min/max values for each axis, I've attached the correct code below (where min/max obtain the smallest/largest values in the list)

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np
import pandas as pd
x_points : List[float] = []
y_points : List[float] = []
x_vel : List[float] = []
y_vel : List[float] = []
#Data Population
#End Data Population
x_min : float = min(x_vel)
y_min : float = min(y_vel)
x_max : float = max(x_vel)
y_max : float = max(y_vel)
xi = np.linspace(x_min, y_max, len(x_points))
yi = np.linspace(y_min, y_max, len(y_points))
X, Y = np.meshgrid(xi, yi)
U = interpolate.griddata((x_points, y_points), x_vel, (X, Y), method='cubic')
V = interpolate.griddata((x_points, y_points), y_vel, (X, Y), method='cubic')
f, ax = plt.subplots(figsize=(6,6))
plt.streamplot(X, Y, U, V, color=U**2+V**2, linewidth=1, cmap=plt.cm.autumn)

The results look roughly like what I was expecting, but are extremely scattered/spaced out I would expect the flow to be much tighter grouped

Any way I can achieve this?

Results

Upvotes: 0

Shintlor
Shintlor

Reputation: 812

At my end the code is working, I skipped declaring the lists though (it is nor necessary).

I had to correct a minor typo -> z_points doesn't exist, I guess you want y_points instead.

I used some mock data to test your code:

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np
import pandas as pd
from scipy import interpolate

x_points = np.random.normal(3,5, size=1000)
y_points = np.random.normal(1,2, size=1000)
x_vel = np.random.exponential(size=1000)
y_vel = np.random.exponential(5,size=1000

xi = np.linspace(-20, 20, len(x_points))
yi = np.linspace(-20, 20, len(y_points))
X, Y = np.meshgrid(xi, yi)
U = interpolate.griddata((x_points, y_points), x_vel, (X, Y), method='cubic')
V = interpolate.griddata((x_points, y_points), y_vel, (X, Y), method='cubic')
f, ax = plt.subplots(figsize=(6,6))
ax.streamplot(X,Y,U,V, density=[0.2,1])

which outputs

Demo Plot

So in the end I guess your input data has not the correct format. How are you populating your data? Maybe recasting the data from a list to a numpy array would already do the trick.

Upvotes: 1

Related Questions