Matplotlib: Plot movements in 3D - python

I have a solver that solves a system of equations in 3 variables. Each iteration, it has a new guess on all three variables. The guesses over iterations look like this:
array([[ 0.86063431, 0.07119279, 1.70377142],
[ 0.86391084, 0.07014899, 1.72184785],
[ 0.86332177, 0.069444 , 1.71182579],
[ 0.86192988, 0.06913941, 1.69818289],
[ 0.86166436, 0.06916367, 1.69527615]])
(Here for 5 iterations). I would like to plot these using matplotlib. I was thinking about having a dot for each of these coordinates, and have a line connecting them to show the order of coordinates.
Is this a good way of visualizing this? How would I do that using matplotlib?

You can plot this as a 3D trajectory with matplotlib:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
points = np.array([[ 0.86063431, 0.07119279, 1.70377142],
[ 0.86391084, 0.07014899, 1.72184785],
[ 0.86332177, 0.069444 , 1.71182579],
[ 0.86192988, 0.06913941, 1.69818289],
[ 0.86166436, 0.06916367, 1.69527615]]).T
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
ax.plot(points[0], points[1], points[2], marker = 'x')
ax.scatter(*points.T[0], color = 'red')
plt.show()

Related

How to rotate a 2d plot along the x and y axis

I would like to rotate the below example image along the x and y axis, 360 degree. Save the rotated images so that I can create a gif from the saved files.
I used the scipy module with numpy but the output doesn't align with the intended output.
import scipy.misc
from scipy import ndimage
import matplotlib.pyplot as plt
img = cv2.imread('ax2_figure.png')
plt.figure(figsize=(15, 15))
for degree in range(5):
plt.subplot(151+degree)
rotated_img = ndimage.rotate(img, degree*60)
plt.imshow(rotated_img, cmap=plt.cm.gray)
plt.axis('off')
plt.show()
The array that was used to generate the plots.
xy = array([[ 2.56565867, -0.68453676],
[ 2.7705649 , -0.76470133],
[ 1.46815589, -1.31265774],
[-2.70396748, -0.29326683],
[-2.20821359, -0.02249133],
[-2.21705997, -0.18584148],
[ 1.30286825, -1.12362756],
[ 1.33454447, -0.36799136],
[ 0.72123042, -0.19116007],
[ 0.699896 , -0.08678013],
[-2.22643656, 0.70455435],
[-1.86659744, 1.38624018],
[-1.74510161, 1.87923624],
[-1.73131744, 1.49670437],
[-0.01485659, 1.07782199],
[ 0.12371347, 1.53934113],
[ 0.18156564, 1.04662112],
[ 1.20251175, 0.68040644],
[ 1.55150657, 0.36432144],
[ 1.56232503, 0.19121897],
[ 2.07646198, -0.02316096],
[ 1.57910992, -0.26536205]])
fig, ax = plt.subplots()
for start, stop in zip(xy[:-1], xy[1:]):
x, y = zip(start, stop)
ax.plot(x, y, color=uniqueish_color())
plt.show()
example image
output image in gif format.
The image is large about 3MB so I added a link to the image.
image

How to plot vector addition in Matplotlib?

I am trying to plot vector addition and I am not getting the result as expected, I am completely new at 3D plotting I need serious help
My plot looks like this:
What I want is to connect the green line to the head of the two arrows. My code looks something like this:
import numpy as np
import matplotlib.pyplot as plt
u = np.array([1, 2, 3]) # vector u
v = np.array([5, 6, 2]) # vector v:
fig = plt.figure()
ax = plt.axes(projection = "3d")
start = [0,0,0]
ax.quiver(start[0],start[1],start[2],u[0],u[1],u[2],color='red')
ax.quiver(start[0],start[1],start[2],v[0],v[1],v[2])
ax.quiver(v[0],v[1],v[2],u[0],u[1],u[2],color="green")
ax.set_xlim([-1,10])
ax.set_ylim([-10,10])
ax.set_zlim([0,10])
plt.show()
Apologies for any kind of mistake , thnks
it's vector addition, just add the vectors
sum_vector = u+v
ax.quiver(start[0], start[1], start[2], sum_vector[0], sum_vector[1], sum_vector[2], color="green")

Plot a non-square matrix according to the value at that point

I have an 2 dimensional array generated randomly as:-
In [159]:
arr
arr
Out[159]:
array([[ 0.22415888, 0.75510844, 0.30900038, 0.88540865],
[ 0.57742895, 0.17051546, 0.5770795 , 0.92893646],
[ 0.39222077, 0.84292636, 0.92571946, 0.3890262 ],
[ 0.83965826, 0.30913694, 0.24132208, 0.85672481]])
I want to plot the intensity of every point according to the value at that position. For example:- 0.83965826 should show up as much darker at position (3,1) than the 0.22415888 at (0,0). I need to do it using matplotlib, seaborn or any other other python visualization tool
is that what you want?
sns.heatmap(a, annot=True)
Full code:
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
a = np.array([[ 0.22415888, 0.75510844, 0.30900038, 0.88540865],
[ 0.57742895, 0.17051546, 0.5770795 , 0.92893646],
[ 0.39222077, 0.84292636, 0.92571946, 0.3890262 ],
[ 0.83965826, 0.30913694, 0.24132208, 0.85672481]])
sns.heatmap(a, annot=True)
plt.show()

Extracting data from a scatter plot in Matplotlib

I'm writing an interface to do scatter plots in Matplotlib, and I'd like to be able to access the data from a python script.
Right now, my interface is doing:
scat = self.axes.scatter(x_data, y_data, label=label, s=size)
With a standard axes.plot I can do something like:
line = self.axes.plot(x_data, y_data)
data = line[0].get_data()
and that works. What I'd like is something similar, but with the scatter plot.
Can anyone suggest a similar method?
A scatter plot is drawn using PathCollection, so the x, y positions are called "offsets":
import numpy as np
import matplotlib.pyplot as plt
f, ax = plt.subplots()
scat = ax.scatter(np.random.randn(10), np.random.randn(10))
print scat.get_offsets()
[[-0.17477838 -0.47777312]
[-0.97296068 -0.98685982]
[-0.18880346 1.16780445]
[-1.65280361 0.2182109 ]
[ 0.92655599 -1.40315507]
[-0.10468029 0.82269317]
[-0.09516654 -0.80651275]
[ 0.01400393 -1.1474178 ]
[ 1.6800925 0.16243422]
[-1.91496598 -2.12578586]]

Discrete colorbar in matplotlib [duplicate]

How does one set the color of a line in matplotlib with scalar values provided at run time using a colormap (say jet)? I tried a couple of different approaches here and I think I'm stumped. values[] is a storted array of scalars. curves are a set of 1-d arrays, and labels are an array of text strings. Each of the arrays have the same length.
fig = plt.figure()
ax = fig.add_subplot(111)
jet = colors.Colormap('jet')
cNorm = colors.Normalize(vmin=0, vmax=values[-1])
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet)
lines = []
for idx in range(len(curves)):
line = curves[idx]
colorVal = scalarMap.to_rgba(values[idx])
retLine, = ax.plot(line, color=colorVal)
#retLine.set_color()
lines.append(retLine)
ax.legend(lines, labels, loc='upper right')
ax.grid()
plt.show()
The error you are receiving is due to how you define jet. You are creating the base class Colormap with the name 'jet', but this is very different from getting the default definition of the 'jet' colormap. This base class should never be created directly, and only the subclasses should be instantiated.
What you've found with your example is a buggy behavior in Matplotlib. There should be a clearer error message generated when this code is run.
This is an updated version of your example:
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import matplotlib.cm as cmx
import numpy as np
# define some random data that emulates your indeded code:
NCURVES = 10
np.random.seed(101)
curves = [np.random.random(20) for i in range(NCURVES)]
values = range(NCURVES)
fig = plt.figure()
ax = fig.add_subplot(111)
# replace the next line
#jet = colors.Colormap('jet')
# with
jet = cm = plt.get_cmap('jet')
cNorm = colors.Normalize(vmin=0, vmax=values[-1])
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet)
print scalarMap.get_clim()
lines = []
for idx in range(len(curves)):
line = curves[idx]
colorVal = scalarMap.to_rgba(values[idx])
colorText = (
'color: (%4.2f,%4.2f,%4.2f)'%(colorVal[0],colorVal[1],colorVal[2])
)
retLine, = ax.plot(line,
color=colorVal,
label=colorText)
lines.append(retLine)
#added this to get the legend to work
handles,labels = ax.get_legend_handles_labels()
ax.legend(handles, labels, loc='upper right')
ax.grid()
plt.show()
Resulting in:
Using a ScalarMappable is an improvement over the approach presented in my related answer:
creating over 20 unique legend colors using matplotlib
I thought it would be beneficial to include what I consider to be a more simple method using numpy's linspace coupled with matplotlib's cm-type object. It's possible that the above solution is for an older version. I am using the python 3.4.3, matplotlib 1.4.3, and numpy 1.9.3., and my solution is as follows.
import matplotlib.pyplot as plt
from matplotlib import cm
from numpy import linspace
start = 0.0
stop = 1.0
number_of_lines= 1000
cm_subsection = linspace(start, stop, number_of_lines)
colors = [ cm.jet(x) for x in cm_subsection ]
for i, color in enumerate(colors):
plt.axhline(i, color=color)
plt.ylabel('Line Number')
plt.show()
This results in 1000 uniquely-colored lines that span the entire cm.jet colormap as pictured below. If you run this script you'll find that you can zoom in on the individual lines.
Now say I want my 1000 line colors to just span the greenish portion between lines 400 to 600. I simply change my start and stop values to 0.4 and 0.6 and this results in using only 20% of the cm.jet color map between 0.4 and 0.6.
So in a one line summary you can create a list of rgba colors from a matplotlib.cm colormap accordingly:
colors = [ cm.jet(x) for x in linspace(start, stop, number_of_lines) ]
In this case I use the commonly invoked map named jet but you can find the complete list of colormaps available in your matplotlib version by invoking:
>>> from matplotlib import cm
>>> dir(cm)
A combination of line styles, markers, and qualitative colors from matplotlib:
import itertools
import matplotlib as mpl
import matplotlib.pyplot as plt
N = 8*4+10
l_styles = ['-','--','-.',':']
m_styles = ['','.','o','^','*']
colormap = mpl.cm.Dark2.colors # Qualitative colormap
for i,(marker,linestyle,color) in zip(range(N),itertools.product(m_styles,l_styles, colormap)):
plt.plot([0,1,2],[0,2*i,2*i], color=color, linestyle=linestyle,marker=marker,label=i)
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.,ncol=4);
UPDATE: Supporting not only ListedColormap, but also LinearSegmentedColormap
import itertools
import matplotlib.pyplot as plt
Ncolors = 8
#colormap = plt.cm.Dark2# ListedColormap
colormap = plt.cm.viridis# LinearSegmentedColormap
Ncolors = min(colormap.N,Ncolors)
mapcolors = [colormap(int(x*colormap.N/Ncolors)) for x in range(Ncolors)]
N = Ncolors*4+10
l_styles = ['-','--','-.',':']
m_styles = ['','.','o','^','*']
fig,ax = plt.subplots(gridspec_kw=dict(right=0.6))
for i,(marker,linestyle,color) in zip(range(N),itertools.product(m_styles,l_styles, mapcolors)):
ax.plot([0,1,2],[0,2*i,2*i], color=color, linestyle=linestyle,marker=marker,label=i)
ax.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.,ncol=3,prop={'size': 8})
U may do as I have written from my deleted account (ban for new posts :( there was). Its rather simple and nice looking.
Im using 3-rd one of these 3 ones usually, also I wasny checking 1 and 2 version.
from matplotlib.pyplot import cm
import numpy as np
#variable n should be number of curves to plot (I skipped this earlier thinking that it is obvious when looking at picture - sorry my bad mistake xD): n=len(array_of_curves_to_plot)
#version 1:
color=cm.rainbow(np.linspace(0,1,n))
for i,c in zip(range(n),color):
ax1.plot(x, y,c=c)
#or version 2: - faster and better:
color=iter(cm.rainbow(np.linspace(0,1,n)))
c=next(color)
plt.plot(x,y,c=c)
#or version 3:
color=iter(cm.rainbow(np.linspace(0,1,n)))
for i in range(n):
c=next(color)
ax1.plot(x, y,c=c)
example of 3:
Ship RAO of Roll vs Ikeda damping in function of Roll amplitude A44

Categories

Resources