import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random
from PIL import Image
import urllib.request
data_array=[]
for i in range(5):
`#I read my all data for each file`
X= `first_column` `#and shape is 1000000`
Y= `second_column`
Z= `third_column`
vx= `......` `and so on. I have 6 column and each column contains 1000000 data`
vy= `.......`
vz= `.......`
`#trying to append data in empty list for each data`
data_array.append(np.array([X, Y, Z, vx, vy, vz]).T)
`#plot `
cmap = cm.get_cmap('seismic')
fig, ax = plt.subplots(figsize=(10,10))
ax = plt.gca()
ax.set_aspect('equal')
graph=plt.scatter(data_array[i] [:,0], data_array[i] [:,1], s=3, alpha=0.5,
lw=0,c=data_array[i] [:,5], cmap=cmap)
plt.xlabel('X [pc] ')
plt.ylabel('Y [pc] ')
`#plot a color bar legend`
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
cbar = plt.colorbar(cax=cax)
cbar.set_label(r'$v_z$ [km/s]')
plt.clim(np.max(vz), np.min(vz))
plt.legend(fontsize='12')
#I am trying to animate my each data sets and make a movie
def animate(i):
graph.set_offsets(np.vstack((X[:i+1], Y[:i+1])).T)
graph.set_sizes(size[:i+1])
colors.append(cm(i))
graph.set_facecolors(colors)
return graph
ani = FuncAnimation(fig, animate, frames=20, repeat=False, interval=200)
plt.show()
I am trying to make a movie from each of scatter plots.
Related
I am trying to animate a plot of geographic coordinates over an image, in this case a snippet of a map. I've managed to produce a static plot but cannot get it to animate. I've tried to animate using the matplotlib animation function, but haven't had any success with it. I am using pandas to read the csv in to Python and matplotlib.pyplot to plot. Below is the code for the static plot.
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('mydata.csv', header=0)
# find max/min, plug into a website, snip area as png and insert as plotmap
BBox = ((df.LONGITUDE.min(), df.LONGITUDE.max(),
df.LATITUDE.min(), df.LATITUDE.max()))
#read the image in, plot points over image
plotmap = "myimage.png"
truthplot = plt.imread(plotmap)
fig, ax = plt.subplots(figsize = (8,8),linewidth = 0.1)
ax.scatter(df.LONGITUDE, df.LATITUDE, zorder=1, alpha= 0.5, c='b', s=10)
plottitle = "test"
ax.set_title(plottitle)
ax.set_xlabel("Longitude")
ax.set_ylabel("Latitude")
ax.set_xlim(BBox[0], BBox[1])
ax.set_ylim(BBox[2], BBox[3])
ax.imshow(truthplot, zorder=0, extent = BBox, aspect= 'equal')
plt.show()
Some example coordinates:
LATITUDE LONGITUDE
30.112342 10.678982
29.443459 11.678997
29.334221 11.889544
28.993448 12.003847
I'm still a newbie; any help is appreciated.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
df = pd.read_csv('mydata.csv', header=0)
# find max/min, plug into a website, snip area as png and insert as plotmap
BBox = ((df.LONGITUDE.min(), df.LONGITUDE.max(),
df.LATITUDE.min(), df.LATITUDE.max()))
#read the image in, plot points over image
plotmap = "myimage.png"
truthplot = plt.imread(plotmap)
fig, ax = plt.subplots(figsize = (8,8),linewidth = 0.1)
plottitle = "test"
ax.set_title(plottitle)
ax.set_xlabel("Longitude")
ax.set_ylabel("Latitude")
ax.set_xlim(BBox[0], BBox[1])
ax.set_ylim(BBox[2], BBox[3])
scat = ax.scatter(df.LONGITUDE, df.LATITUDE, zorder=1, alpha= 0.5, c='b', s=10)
color_data = np.random.random((500, len(df.LATITUDE)))
def update(frame):
scat.set_array(color_data[frame])
return scat,
ani = FuncAnimation(fig, update, frames=range(500), blit=True)
ax.imshow(truthplot, zorder=0, extent = BBox, aspect= 'equal')
plt.show()
I am not sure what you wanted to be animated, that's why I just made the points blink.
But you can easily change your scatter plot all you want in the update function.
scat is a PathCollection, its functions you can find here:
https://matplotlib.org/3.2.1/api/collections_api.html#matplotlib.collections.PathCollection
UPDATE
If you want to build the path step by step, manipulation the PathCollention is not very convenient. I would recommend recreating the obj.
scat = ax.scatter(df.LONGITUDE[0], df.LATITUDE[0], zorder=1, alpha= 0.5, c='b', s=10)
max_frames = 10
def update(frame):
scat = ax.scatter(df.LONGITUDE[:(frame * (len(df.LONGITUDE) + 1))//max_frames],
df.LATITUDE[:(frame * (len(df.LATITUDE) + 1))//max_frames],
zorder=1, alpha= 0.5, c='b', s=10)
return scat,
You can try this, if you want to use a scatter plot on a DataFrame directly:
BBox = ((df['LONGITUDE'].min(), df['LONGITUDE'].max(),
df['LATITUDE'].min(), df['LATITUDE'].max()))
plotmap = 'myimage.png'
truthplot = plt.imread(plotmap)
ax = df.plot.scatter(x='LONGITUDE', y='LATITUDE', c='Red')
plottitle = "test"
ax.set_title(plottitle)
ax.set_xlabel("Longitude")
ax.set_ylabel("Latitude")
ax.set_xlim(BBox[0], BBox[1])
ax.set_ylim(BBox[2], BBox[3])
ax.imshow(truthplot, zorder=0, extent = BBox, aspect= 'equal')
plt.show()
I draw my data points with ax.scatter() and connect the data points with a fit using ax.plot().
How do I create a common entry in the legend that combines the marker for the data point with the line of the fit? I want to get a legend entry as I would get it for ax.plot(x, y, '-o', label = 'abc').
I have created the following minimal example:
import matplotlib.pyplot as plt
import numpy as np
x_scatter = np.linspace(0,10,10)
x_line = np.linspace(0,10,100)
fig, ax = plt.subplots()
for i in range(5):
ax.scatter(x_scatter, np.sin(x_scatter) + i, label = i)
ax.plot(x_line, np.sin(x_line)+i)
plt.legend(loc='best')
plt.show()
This 'hack' should work:
import matplotlib.pyplot as plt
import numpy as np
x_scatter = np.linspace(0,10,10)
x_line = np.linspace(0,10,100)
fig, ax = plt.subplots()
prop = ax._get_lines.prop_cycler
for i in range(5):
color = next(prop)['color']
ax.scatter(x_scatter, np.sin(x_scatter) + i, color=color)
ax.plot(x_line, np.sin(x_line)+i, color=color)
ax.plot([], [], '-o', color=color, label = i)
plt.legend(loc='best')
plt.show()
MWE:
I would like the title position same as in the graph :
Here is my code :
import matplotlib.pyplot as plt
import numpy as np
import random
fig, ax = plt.subplots()
x = random.sample(range(256),200)
y = random.sample(range(256),200)
cor=np.corrcoef(x,y)
plt.scatter(x,y, color='b', s=5, marker=".")
#plt.scatter(x,y, label='skitscat', color='b', s=5, marker=".")
ax.set_xlim(0,300)
ax.set_ylim(0,300)
plt.xlabel('x')
plt.ylabel('y')
plt.title('Correlation Coefficient: %f'%cor[0][1])
#plt.legend()
fig.savefig('plot.png', dpi=fig.dpi)
#plt.show()
But this gives :
How do I fix this title position?
assign two corresponded value to X and Y axis. notice! to have title inside graph, values should be in (0,1) interval. you can see a sample code here:
import matplotlib. pyplot as plt
A= [2,1,4,5]; B = [3,2,-2,1]
plt.scatter(A,B)
plt.title("title", x=0.9, y=0.9)
plt.xlabel("x-axis")
plt.ylabel("y-axis")
plt.show()
It will be unnecessarily complicated to move the title at some arbitrary position inside the axes.
Instead one would rather create a text at the desired position.
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
x = np.random.randint(256,size=200)
y = np.random.randint(256,size=200)
cor=np.corrcoef(x,y)
ax.scatter(x,y, color='b', s=5, marker=".")
ax.set_xlim(0,300)
ax.set_ylim(0,300)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.text(0.9, 0.9, 'Correlation Coefficient: %f'%cor[0][1],
transform=ax.transAxes, ha="right")
plt.show()
I'm trying to create an animated map plot using smopy and matplotlib in jupyter, but when I run the code I get two figures instead of one. The first figure is shown above the map and empty. Can anyone tell me how to fix this so that only the animation is drawn?
import smopy
import matplotlib.animation as animation
n= 1000
%matplotlib notebook
def update(curr):
if curr == n-100:
a.event_source.stop()
lons = crime_df.X[curr:curr+100]
lats = crime_df.Y[curr:curr+100]
x,y = map.to_pixels(lats,lons)
ax.scatter(x, y, c='r', alpha=0.7, s=200)
plt.title(curr)
fig = plt.figure()
ax = smopy.Map((37.6624,-122.5168,37.8231,-122.3589), z=12)
ax = ax.show_mpl(figsize=(8,8))
a = animation.FuncAnimation(fig, update, interval=100)
You should not create an additional figure, if that is undersired: Leave out plt.figure().
import smopy
import matplotlib.pyplot as plt
import matplotlib.animation as animation
n= 1000
%matplotlib notebook
def update(curr):
if curr == n-100:
a.event_source.stop()
lons = crime_df.X[curr:curr+100]
lats = crime_df.Y[curr:curr+100]
x,y = map.to_pixels(lats,lons)
ax.scatter(x, y, c='r', alpha=0.7, s=200)
plt.title(curr)
m = smopy.Map((37.6624,-122.5168,37.8231,-122.3589), z=12)
ax = m.show_mpl(figsize=(8,8))
a = animation.FuncAnimation(ax.figure, update, interval=100)
Alternatively create the figure beforehands,
fig, ax = plt.subplots(figsize=(8,8))
m = smopy.Map((37.6624,-122.5168,37.8231,-122.3589), z=12)
m.show_mpl(ax = ax)
a = animation.FuncAnimation(fig, update, interval=100)
Consider this example
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
plt.subplot(121)
img = plt.imshow([np.arange(0,1,.1)],aspect="auto")
ax = plt.gca()
divider = make_axes_locatable(ax)
cax = divider.append_axes("bottom", size="3%", pad=0.5)
plt.colorbar(img, cax=cax, orientation='horizontal')
plt.subplot(122)
plt.plot(range(2))
plt.show()
I want to make these two figures (plot region without colorbar) of the same size.
The size is automatically adjusted if the colorbar is plotted vertically or if two rows are used (211, 212) instead of two columns.
One can basically do the same for the second subplot as for the first, i.e. create a divider and append an axes with identical parameters, just that in this case, we don't want a colorbar in the axes, but instead simply turn the axis off.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
ax = plt.subplot(121)
img = ax.imshow([np.arange(0,1,.1)],aspect="auto")
divider = make_axes_locatable(ax)
cax = divider.append_axes("bottom", size="3%", pad=0.5)
plt.colorbar(img, cax=cax, orientation='horizontal')
ax2 = plt.subplot(122)
ax2.plot(range(2))
divider2 = make_axes_locatable(ax2)
cax2 = divider2.append_axes("bottom", size="3%", pad=0.5)
cax2.axis('off')
plt.show()
You can now do this without recourse to an extra toolkit by using constrained_layout:
import numpy as np
import matplotlib.pyplot as plt
fig, axs = plt.subplots(1, 2, constrained_layout=True)
ax = axs[0]
img = ax.imshow([np.arange(0,1,.1)],aspect="auto")
fig.colorbar(img, ax=ax, orientation='horizontal')
axs[1].plot(range(2))
plt.show()