Plotting a scatter over a dataset - python-3.x

I have a dataset from which I intent to make a scatterplot. It consists of 2 columns, where the first column should be used as x, and the other as y, so that each dot = x[0 firstcolumn], x[0 secondcolumn].
However I keep getting "x and y must be same size", and I cannot make out how to plot this. Below is my latest attempt on making them the same size, however unsuccesful
import numpy as np
import matplotlib.pyplot as plt
X = numpy.loadtxt('data')
x = range(len(X))
plt.scatter(x,X, color='blue', label = "car")
plt.show()

Related

How to plot vertical stacked graph from different text files?

I have 5 txt files which contain data give me the effect of increasing heat on my samples and I want plot them in a vertical stacked graph, Where the final figure is 5 vertical stacked chart sharing the same X-axis and each line in a separate one to reveal the difference between them.
I wrote this code:
import glob
import pandas as pd
import matplotlib.axes._axes as axes
import matplotlib.pyplot as plt
input_files = glob.glob('01-input/RR_*.txt')
for file in input_files:
data = pd.read_csv(file, header=None, delimiter="\t").values
x = data[:,0]
y = data[:,1]
plt.subplot(2, 1, 1)
plt.plot(x, y, linewidth=2, linestyle=':')
plt.tight_layout()
plt.xlabel('x-axis')
plt.ylabel('y-axis')
But the result is only one graph containing all the lines:
I want to get the following chart:
import matplotlib.pyplot as plt
import numpy as np
# just a dummy data
x = np.linspace(0, 2700, 50)
all_data = [np.sin(x), np.cos(x), x**0.3, x**0.4, x**0.5]
n = len(all_data)
n_rows = n
n_cols = 1
fig, ax = plt.subplots(n_rows, n_cols) # each element in "ax" is a axes
for i, y in enumerate(all_data):
ax[i].plot(x, y, linewidth=2, linestyle=':')
ax[i].set_ylabel('y-axis')
# You can to use a list of y-labels. Example:
# my_labels = ['y1', 'y2', 'y3', 'y4', 'y5']
# ax[i].set_ylabel(my_labels[i])
# The "my_labels" lenght must be "n" too
plt.xlabel('x-axis') # add xlabel at last axes
plt.tight_layout()

plt.legend only adds first element to scatter plot

I am trying to add a legend to my scatter plot with 13 classes, however, with my code below, I am only able to get the first label. Can you assist me in generating the full list to show up in the legend of the scatter plot?
Here is my example code:
from sklearn.datasets import make_blobs
from matplotlib import pyplot
from pandas import DataFrame
# generate 2d classification dataset
X, y = make_blobs(n_samples=1000, centers=13, n_features=2)
classes = [f"class {i}" for i in range(13)]
#fig = plt.figure()
plt.figure(figsize=(15, 12))
scatter = plt.scatter(
x=X[:,0],
y=X[:,1],
s = 20,
c = y,
cmap='Spectral'
#c=[sns.color_palette()[x] for x in y_train_new]
)
plt.gca().set_aspect('equal', 'datalim')
plt.legend(classes)
plt.title('Dataset', fontsize=24)
You can do that by replacing the plt.legend(classes) in your code by this line... I hope this is what you are looking for. I am using matplotlib 3.3.4.
plt.legend(handles=scatter.legend_elements()[0], labels=classes)
Output plot

Matplotlib get_ylim() changing data transformation result

"get_ylim()" is changing the result of the transformation from data to display coordinates in matplotlib (I'm using version 3.2.1). Is it supposed to change axis properties? It's the same effect using "get_xlim()".
Here is my code:
import matplotlib.pyplot as plt
import numpy as np
dpi = 80
plt.rcParams.update({'font.size': 12})
fig, ax = plt.subplots(figsize=(1280/dpi, 720/dpi), dpi=dpi)
x = np.arange(200)
y = - 0.1 * x
ax.plot(x, y)
points = ax.transData.transform(np.vstack((x, y)).T).astype(int)
print(points[:5])
ax.get_ylim()
points = ax.transData.transform(np.vstack((x, y)).T).astype(int)
print(points[:5])
Both prints output different results only with the ax.get_ylim() in place.

Plotting a dot that moves along side a dispersive wave?

How would I go on about plotting a dot that moves along a wave pack/superposition. I saw this on the website and wanted to try for myself.https://blog.soton.ac.uk/soundwaves/further-concepts/2-dispersive-waves/. So I know how to animate a superpositon of two sine waves. But how would I plot a dot that moves along it? I won't post my entire code, but it looks somewhat like this
import matplotlib.pyplot as plt
import numpy as np
N = 1000
x = np.linspace(0,100,N)
wave1 = np.sin(2*x)
wave2 = np.sin(3*x)
sWave = wave1+wave2
plt.plot(x,sWave)
plt.ion()
for t in np.arange(0,400):
sWave.set_ydata(sWave)
plt.draw()
plt.pause(.1)
plt.ioff()
plt.show()
Note that this is just a quick draft of my original code.
You can add a scatter and update its data in a loop by using .set_offsets().
import matplotlib.pyplot as plt
import numpy as np
N = 1000
x = np.linspace(0, 100, N)
wave1 = np.sin(2*x)
wave2 = np.sin(3*x)
sWave = wave1 + wave2
fig, ax = plt.subplots()
ax.plot(x, sWave)
scatter = ax.scatter([], [], facecolor="red") # Initialize an empty scatter.
for t in range(N):
scatter.set_offsets((x[t], sWave[t])) # Modify that scatter's data.
fig.canvas.draw()
plt.pause(.001)

Matplotlib get all axes artist objects for ArtistAnimation?

I am trying to make an animation using ArtistAnimation like this:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots()
ims = []
for i in range(60):
x = np.linspace(0,i,1000)
y = np.sin(x)
im = ax.plot(x,y, color='black')
ims.append(im)
ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True,
repeat_delay=1000)
plt.show()
This animates a sine wave growing across the figure. Currently I'm just adding the Lines2D object returned by ax.plot() to ims. However, I would like to potentially draw multiple overlapping plots on the Axes and adjust the title, legend and x-axis range for each frame. How do I get an object that I can add to ims after plotting and making all the changes I want for each frame?
The list you supply to ArtistAnimation should be a list of lists of artists, one list per frame.
artist_list = [[line1a, line1b, title1], [line2a, line2b, title2], ...]
where the first list is shown in the first frame, the second list in the second frame etc.
The reason your code works is that ax.plot returns a list of lines (in your case only a list of a single line).
In any case, the following might be a more understandable version of your code where an additional text is animated.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots()
artist_list = []
for i in range(60):
x = np.linspace(0,i,1000)
y = np.sin(x)
line, = ax.plot(x,y, color='black')
text = ax.text(i,0,i)
artist_list.append([line, text])
ani = animation.ArtistAnimation(fig, artist_list, interval=50, blit=True,
repeat_delay=1000)
plt.show()
In general, it will be hard to animate changing axes limits with ArtistAnimation, so if that is an ultimate goal consider using a FuncAnimation instead.

Resources