I would like to use any vector as an axis in plt.imshow().
A = np.random.rand(4, 4)
x = np.array([1, 2, 3, 8])
y = np.array([-1, 0, 2, 3])
I imagine something like this:
plt.imshow(a, x_ax=x, y_ax=y)
I know there is an extent parameter available, but sadly it does not allow for non-equally spaced vectors.
Can anyone please help? Thanks in advance.
Imshow plots are always equally spaced. The question would be if you want to have
(a) an equally spaced plot with unequally spaced labels, or
(b) an unequally spaced plot with labels to scale.
(a) equally spaced plot
import numpy as np
import matplotlib.pyplot as plt
a = np.random.rand(4, 4)
x = np.array([1, 2, 3, 8])
y = np.array([-1, 0, 2, 3])
plt.imshow(a)
plt.xticks(range(len(x)), x)
plt.yticks(range(len(y)), y)
plt.show()
(b) unequally spaced plot
import numpy as np
import matplotlib.pyplot as plt
a = np.random.rand(3, 3)
x = np.array([1, 2, 3, 8])
y = np.array([-1, 0, 2, 3])
X,Y = np.meshgrid(x,y)
plt.pcolormesh(X,Y,a)
plt.xticks(x)
plt.yticks(y)
plt.show()
Note that in this case the "vector" would specify the edges of the grid, thus they would only allow for a 3x3 array.
Related
Let's say I have a equation y=a*x, where a=[1,2,3,4] and x,y each have a set of values.
I get that for a simple x vs y plot plt.scatter(x,y) is enough, but how can I make a scatter plot of x vs y for each a?
This will create a list of axis objects and then it will make a scatterplot to each of them.
I imported numpy in order to multiply the lists, which are now numpy arrays.
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 4])
y = np.array([4, 5, 2])
a = np.array([1, 5, 2])
#create the axis objects
fig, axis = plt.subplots(1, len(a))
for i in range(len(a)):
axis[i].scatter(x, y * a[i])
I have 6 points in the (x,y) plane: x=[x1,x2,x3,x4,x5,x6] and y=[y1,y2,y3,y4,y5,y6]
import matplotlib.pyplot as plt
x = [0, 2, 4, 0, 2, 4, 0, 2, 4]
y = [0, 0, 0, 3, 3, 3, 7, 7, 7]
plt.scatter(x, y)
plt.show()
I want to between the points, draw entirely parallel lines on each axis x,y(like photo). and how to hide x and y axis on diagram. I want to draw a 2D view of the beams and columns of 3 story building; does matplotlib bring me to my goal or should I go to other libraries?
Absolutely matplotlib can do this. Take a look at their Rectangle Patch:
Example usage (you'll have to modify this to your needs):
import matplotlib.pyplot as plt
import matplotlib.patches as patches
fig = plt.figure()
ax = fig.add_subplot()
rect = patches.Rectangle(
(0.1, 0.1),
0.5,
0.5,
fill=False
)
ax.add_patch(rect)
fig.show()
I have something similar to this problem respectivly the answer of this problem: RBF interpolation: LinAlgError: singular matrix
But I want to do the probability distribution with rbf.
My code until now:
from scipy.interpolate.rbf import Rbf # radial basis functions
import cv2
import matplotlib.pyplot as plt
import numpy as np
x = [1, 1, 2 ,3, 4, 4, 2, 6, 7]
y = [0, 2, 5, 6, 2, 4, 1, 5, 2]
rbf_adj = Rbf(x, y, function='gaussian')
plt.figure()
# Plotting the original points.
plot3 = plt.plot(x, y, 'ko', markersize=12) # the original points.
plt.show()
My problem is I have only coordinates of the points: x, y
But what can i use for z and d?
This is my error message:
numpy.linalg.linalg.LinAlgError: Matrix is singular.
This is, first, a 1D example to emphasis the difference between the Radial Basis Function interpolation and the Kernel Density Estimation of a probability distribution:
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
from scipy.interpolate.rbf import Rbf # radial basis functions
from scipy.stats import gaussian_kde
coords = np.linspace(0, 2, 7)
values = np.ones_like(coords)
x_fine = np.linspace(-1, 3, 101)
rbf_interpolation = Rbf(coords, values, function='gaussian')
interpolated_y = rbf_interpolation(x_fine)
kernel_density_estimation = gaussian_kde(coords)
plt.figure()
plt.plot(coords, values, 'ko', markersize=12)
plt.plot(x_fine, interpolated_y, '-r', label='RBF Gaussian interpolation')
plt.plot(x_fine, kernel_density_estimation(x_fine), '-b', label='kernel density estimation')
plt.legend(); plt.xlabel('x')
plt.show()
And this is the 2D interpolation using Gaussian RBF for the provided data, and by setting arbitrarily the values to z=1:
from scipy.interpolate.rbf import Rbf # radial basis functions
import matplotlib.pyplot as plt
import numpy as np
x = [1, 1, 2 ,3, 4, 4, 2, 6, 7]
y = [0, 2, 5, 6, 2, 4, 1, 5, 2]
z = [1]*len(x)
rbf_adj = Rbf(x, y, z, function='gaussian')
x_fine = np.linspace(0, 8, 81)
y_fine = np.linspace(0, 8, 82)
x_grid, y_grid = np.meshgrid(x_fine, y_fine)
z_grid = rbf_adj(x_grid.ravel(), y_grid.ravel()).reshape(x_grid.shape)
plt.pcolor(x_fine, y_fine, z_grid);
plt.plot(x, y, 'ok');
plt.xlabel('x'); plt.ylabel('y'); plt.colorbar();
plt.title('RBF Gaussian interpolation');
How can we plot 2D math vectors with matplotlib? Does anyone have an example or suggestion about that?
I have a couple of vectors stored as 2D numpy arrays, and I would like to plot them as directed edges.
The vectors to be plotted are constructed as below:
import numpy as np
# a list contains 3 vectors;
# each list is constructed as the tail and the head of the vector
a = np.array([[0, 0, 3, 2], [0, 0, 1, 1], [0, 0, 9, 9]])
Edit:
I just added the plot of the final answer of tcaswell for anyone interested in the output and want to plot 2d vectors with matplotlib:
The suggestion in the comments by halex is correct, you want to use quiver (doc), but you need to tweak the properties a bit.
import numpy as np
import matplotlib.pyplot as plt
soa = np.array([[0, 0, 3, 2], [0, 0, 1, 1], [0, 0, 9, 9]])
X, Y, U, V = zip(*soa)
plt.figure()
ax = plt.gca()
ax.quiver(X, Y, U, V, angles='xy', scale_units='xy', scale=1)
ax.set_xlim([-1, 10])
ax.set_ylim([-1, 10])
plt.draw()
plt.show()
It's pretty straightforward. Hope this example helps.
import matplotlib.pyplot as plt
import numpy as np
x = np.random.normal(10,5,100)
y = 3 + .5*x + np.random.normal(0,1,100)
myvec = np.array([x,y])
plt.plot(myvec[0,],myvec[1,],'ro')
plt.show()
Will produce:
To plot the arrays you can just slice them up into 1D vectors and plot them. I'd read the full documentation of matplotlib for all the different options. But you can treat a numpy vector as if it were a normal tuple for most of the examples.
I'm trying to start 2D contour plot for a flow net and I'm having trouble getting the initial grid to show up properly.
Given the number of columns and the number of rows, how can I write a function that will plot a grid so that all points in the given range appear?
I tried plotting for 4 columns and 3 rows of points by doing this:
r = 3
c = 4
x = [i for i in range(c)]
y = [i for i in range(r)]
plot(x,y,'ro')
grid()
show()
and get this error:
'ValueError: x and y must have same first dimension'
So I tried testing it on a 4x4 grid and got this and I get close to what I want, however it only plots points (0,0), (1,1), (2,2), and (3,3)
However, I also want the points (0,0), (1,0), (2,0), (3,0), (1,0), (1,1)...(3,2), (3,3) to appear, as I will later need to plot vectors from this point indicating the direction of flow for my flow net.
Sorry, I know my terminology isn't that great. Does anyone know how to do this and how to make it work for grids that aren't square?
You could use itertools.product to generate the desired points.
Use plt.scatter to plot the points
Use plt.quiver to plot the vector field. (Relevant code taken from these SO answers)
import numpy as np
import matplotlib.pyplot as plt
import itertools
r = 3
c = 4
x = np.linspace(0, c, c+1)
y = np.linspace(0, r, r+1)
pts = itertools.product(x, y)
plt.scatter(*zip(*pts), marker='o', s=30, color='red')
X, Y = np.meshgrid(x, y)
deg = np.arctan(Y**3 - 3*Y-X)
QP = plt.quiver(X, Y, np.cos(deg), np.sin(deg))
plt.grid()
plt.show()
r = 3
c = 4
x = [i % c for i in range(r*c)]
y = [i / c for i in range(r*c)]
print x
print y
Gives:
[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2]
When used to draw graph as you did it produces desired result.
The first two arguments specify your x and y components. So the number of points must match. I think what you want is something like:
from itertools import product
import matplotlib.pyplot as plt
points = np.array(list(product(range(3),range(4))))
plt.plot(points[:,0],points[:,1],'ro')
plt.show()