Plot or reshape 2D array matplotlib - python

i have no idea how can i plot scatter with a 2D array of this type:
a=[[x0,t0],[x1,t1],...,[xn,tn]]
the plot should be x vs t, maybe instead of doing this with a maplotlib routine be able to reshape a to obtain:
a=[[x0,x1,...,xn],[t0,t1,...,tn]]
thanks!

Assuming your data starts in the format a = [[x0, t0]]:
Split x & t into separate lists, then you can pass them into matplotlib.
import matplotlib.pyplot as plt
x = [i[0] for i in a]
t = [i[1] for i in a]
plt.plot(x, t)

You can use numpy.transpose:
import numpy as np
a=[["x0","t0"],["x1","t1"],["xn","tn"]]
np.transpose(a)
# array([['x0', 'x1', 'xn'],
# ['t0', 't1', 'tn']],
# dtype='<U2')

Related

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")

Strange output in matplotlib

Can someone explain why I get this strange output when running this code:
import matplotlib.pyplot as plt
import numpy as np
def x_y():
return np.random.randint(9999, size=1000), np.random.randint(9999, size=1000)
plt.plot(x_y())
plt.show()
The output:
Your data is a tuple of two 1000 length arrays.
def x_y():
return np.random.randint(9999, size=1000), np.random.randint(9999, size=1000)
xy = x_y()
print(len(xy))
# > 2
print(xy[0].shape)
# > (1000,)
Let's read pyplot's documentation:
plot(y) # plot y using x as index array 0..N-1
Thus pyplot will plot a line between (0, xy[0][i]) and (1, xy[1][i]), for i in range(1000).
You probably try to do this:
plt.plot(*x_y())
This time, it will plot 1000 points joined by lines: (xy[0][i], xy[1][i]) for i in range 1000.
Yet, the lines don't represent anything here. Therefore you probably want to see individual points:
plt.scatter(*x_y())
Your function x_y is returning a tuple, assigning each element to a variable gives the correct output.
import matplotlib.pyplot as plt
import numpy as np
def x_y():
return np.random.randint(9999, size=1000), np.random.randint(9999, size=1000)
x, y = x_y()
plt.plot(x, y)
plt.show()

1D multiple lines plot with pandas

I have a dataframe with x1 and x2 columns. I want to plot each row as an unidimensional line where x1 is the start and x2 is the end. Follows I have my solution which is not very cool. Besides it is slow when plotting 900 lines in the same plot.
Create some example data:
import numpy as np
import pandas as pd
df_lines = pd.DataFrame({'x1': np.linspace(1,50,50)*2, 'x2': np.linspace(1,50,50)*2+1})
My solution:
import matplotlib.pyplot as plt
def plot(dataframe):
plt.figure()
for item in dataframe.iterrows():
x1 = int(item[1]['x1'])
x2 = int(item[1]['x2'])
plt.hlines(0,x1,x2)
plot(df_lines)
It actually works but I think it could be improved. Thanks in advance.
You can use DataFrame.apply with axis=1 for process by rows:
def plot(dataframe):
plt.figure()
dataframe.apply(lambda x: plt.hlines(0,x['x1'],x['x2']), axis=1)
plot(df_lines)
Matplotlib can save a lot of time drawing lines, when they are organized in a LineCollection. Instead of drawing 50 individual hlines, like the other answers do, you create one single object.
Such a LineCollection requires an array of the line vertices as input, it needs to be of shape (number of lines, points per line, 2). So in this case (50,2,2).
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
df_lines = pd.DataFrame({'x1': np.linspace(1,50,50)*2,
'x2': np.linspace(1,50,50)*2+1})
segs = np.zeros((len(df_lines), 2,2))
segs[:,:,0] = df_lines[["x1","x2"]].values
fig, ax = plt.subplots()
line_segments = LineCollection(segs)
ax.add_collection(line_segments)
ax.set_xlim(0,102)
ax.set_ylim(-1,1)
plt.show()
I add to the nice #jezrael response the possibility to do this in the numpy framework using numpy.apply_along_axis. Performance-wise it is equivalent to DataFrame.apply:
def plot(dataframe):
plt.figure()
np.apply_along_axis(lambda x: plt.hlines(0,x[0],x[1]), 1,dataframe.values)
plt.show()
plot(df_lines)

Plotting list of lists in a same graph in Python

I am trying to plot (x,y) where as y = [[1,2,3],[4,5,6],[7,8,9]].
Say, len(x) = len(y[1]) = len(y[2])..
The length of the y is decided by the User input. I want to plot multiple plots of y in the same graph i.e, (x, y[1],y[2],y[3],...). When I tried using loop it says dimension error.
I also tried: plt.plot(x,y[i] for i in range(1,len(y)))
How do I plot ? Please help.
for i in range(1,len(y)):
plt.plot(x,y[i],label = 'id %s'%i)
plt.legend()
plt.show()
Assuming some sample values for x, below is the code that could give you the desired output.
import matplotlib.pyplot as plt
x = [1,2,3]
y = [[1,2,3],[4,5,6],[7,8,9]]
plt.xlabel("X-axis")
plt.ylabel("Y-axis")
plt.title("A test graph")
for i in range(len(y[0])):
plt.plot(x,[pt[i] for pt in y],label = 'id %s'%i)
plt.legend()
plt.show()
Assumptions: x and any element in y are of the same length.
The idea is reading element by element so as to construct the list (x,y[0]'s), (x,y[1]'s) and (x,y[n]'s.
Edited: Adapt the code if y contains more lists.
Below is the plot I get for this case:
Use a for loop to generate the plots and use the .show() method after the for loop.
import matplotlib.pyplot as plt
for impacts in impactData:
timefilteredForce = plt.plot(impacts)
timefilteredForce = plt.xlabel('points')
timefilteredForce = plt.ylabel('Force')
plt.show()
impactData is a list of lists.

Python scatter-plot: Conditions for marker styles?

I have a data set I wish to plot as scatter plot with matplotlib, and a vector the same size that categorizes and labels the data points (discretely, e.g. from 0 to 3). I want to use different markers for different labels (e.g. 'x' for 0, 'o' for 1 and so on). How can I solve this elegantly? I am quite sure I am just missing out on something, but didn't really find it, and my naive approaches failed so far...
What about iterating over all markers like this:
import numpy as np
import matplotlib.pyplot as plt
x = np.random.rand(100)
y = np.random.rand(100)
category = np.random.random_integers(0, 3, 100)
markers = ['s', 'o', 'h', '+']
for k, m in enumerate(markers):
i = (category == k)
plt.scatter(x[i], y[i], marker=m)
plt.show()
Matplotlib does not accepts different markers per plot.
However, a less verbose and more robust solution for large dataset is using the pandas and seaborn library:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
x = [48.959, 49.758, 49.887, 50.593, 50.683 ]
y = [122.310, 121.29, 120.525, 120.252, 119.509]
z = [136.993, 133.128, 143.710, 129.088, 139.860]
kmean = np.array([0, 1, 0, 2, 2])
df = pd.DataFrame({'x':x,'y':y,'z':z, 'km_z':kmean})
sns.scatterplot(data = df, x='x', y='y', hue='km_z', style='km_z')
which produces the following output
Additionally you can use the pandas.cut function to plot bins (Its something I regularly need to produce graphs where I can use a third continuous value as a parameter). The way to use it is :
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
x = [48.959, 49.758, 49.887, 50.593, 50.683 ]
y = [122.310, 121.29, 120.525, 120.252, 119.509]
z = [136.993, 133.128, 143.710, 129.088, 139.860]
df = pd.DataFrame({'x':x,'y':y,'z':z})
df['bins'] = pd.cut(df.z, bins=3)
sns.scatterplot(data = df, x='x', y='y', hue='bins', style='bins')
and it produces the following example:
I've used the latter method to produce graphs like the following:

Categories

Resources