Rotating labels on second axis - matplotlib

I am adding a second x-axis to my plot like this:
ax2 = ax.twiny()
offset = 0, -25
new_axisline = ax2.get_grid_helper().new_fixed_axis
ax2.axis["bottom"] = new_axisline(loc="bottom", axes=ax2, offset=offset)
ax2.axis["top"].set_visible(False)
ax2.set_xticks(xticks)
ax2.xaxis.set_major_formatter(ticker.NullFormatter())
ax2.xaxis.set_minor_locator(ticker.FixedLocator(xticks))
ax2.xaxis.set_minor_formatter(ticker.FixedFormatter(xticks_labels))
the problem is I don't know how I can rotate the labels from there.
Also: If I add ticks to my first axis:
plt.xticks(xticks1, xticks1_labels, rotation='vertical')
the rotation argument gets ignored and I don't understand why either.
I have tried
ax2.set_xticklabels(ax2.xaxis.get_minorticklabels(), rotation=45)
but it also has no effect.
Any help would be appreciated.
You can take a look at the complete plotting logic below:
def event_plot(event_list, labels=None, figsize=(16, 9), padding=0.85, grid=False, title=None, colors=None):
fig = plt.figure(figsize=figsize)
ax = SubplotHost(fig, 111)
# ax = fig.add_subplot(111)
fig.add_subplot(ax)
ax.grid(grid)
if title is not None:
ax.set_title(title)
max_end = 0
for i, events in enumerate(event_list):
for event in events:
start = event[0]
end = event[1]
max_end = max(max_end, end)
y = (i, i + padding)
c = 'red' if colors is None else colors[i]
plt.fill_between([start, end], y[0], y2=y[1], color=c, alpha=0.35, linewidth=0.0)
plt.legend(['Recording data available for channel'], loc='upper center')
if labels is not None:
labels_ids = np.asarray(range(len(labels))) + 1
labels_y = labels_ids - 0.5 - (1 - padding) / 2.
plt.yticks(labels_y, labels)
for y in labels_y:
plt.axhline(y, alpha=0.125, color='k', linestyle='--')
return ax, fig
def plot_case_windows(all_records, case_windows, filename_title, filename=None):
channel_event_list = list()
labels = list()
for group_name, group in all_records.channel_groups.items():
[(labels.append(x[0]), channel_event_list.append(x[1])) for x in group.items()]
recording_time = all_records.end - all_records.start
title = 'File: {:s}, recording time: {:d} sec'.format(os.path.basename(filename_title), int(recording_time))
ax1, fig = event_plot(channel_event_list, title=title, labels=labels)
xticksmax = 0
xticksmin = float('Inf')
xticks1 = list()
xticks1_labels = list()
xticks2 = list()
xticks2_labels = list()
for case_win in case_windows:
xticks1.append(int(case_win.start + (case_win.end - case_win.start)/2.))
xticks2.append(case_win.start)
xticksmax = max(xticksmax, case_win.end)
xticksmin = min(xticksmin, case_win.start)
xticks1_labels.append(case_win.name)
xticks2_labels.append(str(case_win.start) + ' s')
plt.axvline(x=case_win.start, color='k', linestyle='--')
plt.axvline(x=case_win.end, color='k', linestyle='--')
xticks2 = (np.asarray(xticks2) - xticksmin) / (xticksmax - xticksmin)
plt.xlim([xticksmin, xticksmax])
ax1.set_xticks(xticks1)
ax1.xaxis.set_major_formatter(ticker.NullFormatter())
ax1.xaxis.set_minor_locator(ticker.FixedLocator(xticks1))
ax1.xaxis.set_minor_formatter(ticker.FixedFormatter(xticks1_labels))
ax2 = ax1.twiny()
offset = 0, -20
new_axisline = ax2.get_grid_helper().new_fixed_axis
ax2.axis["bottom"] = new_axisline(loc="bottom", axes=ax2, offset=offset)
ax2.axis["top"].set_visible(False)
ax2.set_xticks(xticks2)
ax2.xaxis.set_major_formatter(ticker.NullFormatter())
ax2.xaxis.set_minor_locator(ticker.FixedLocator(xticks2))
ax2.xaxis.set_minor_formatter(ticker.FixedFormatter(xticks2_labels))
plt.setp(ax2.xaxis.get_minorticklabels(), rotation=45)
# ax2.set_xticklabels(ax1.xaxis.get_minorticklabels(), rotation=45)
#plt.show()
plt.tight_layout()
if filename:
plt.savefig(filename)

Related

Matplotlib Logarithmic Radar Charts - Remove all values below 0.5 and show last ytick

If you look in the logarithmic radar chart below, there are two changes I would like, if anyone knows the correct way to code:
1)Display a ytick label for the max value (51.81), as it currently gives the top value as 31.62
2)A way to set all values below 0.1 to 0, without causing divide by zero errors.
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(111, polar=True)
np.seterr(divide = 'warn')
sample = samplelistmalshare
get_mag = lambda x: 10**min(np.floor(np.log10(x)))
init_mag = get_mag(sample)
print("init_mag")
print(init_mag)
print("gm")
print(get_mag)
sample = np.array(sample) / get_mag(sample)
N = len(sample)
theta = np.arange(0, 2 * np.pi, 2 * np.pi / N)
bars = ax.bar(theta, np.log10(sample), width=0.4, color = '#003F5C')
ax.set_xticks(theta)
ax.set_xticklabels([' Delayed\n Execution', ' File\n Opening', 'Firewall\nModification', 'Permission \nModification ', 'Persistence ', 'Proxied \nExecution ', 'Reconnaissance ', ' Registry\n Modification', ' Task\n Stopping'], visible=False)
dat = np.log10(sample)
print(max(dat))
#exit()
ax.set_ylim(0,max(dat))
ax.xaxis.grid(False)
ax.yaxis.grid(True)
precision = 2 # Change to your desired decimal precision
ax.set_yticklabels([str(round((10 ** x) * init_mag, precision)) for x in ax.get_yticks()])
for test in ax.get_yticks():
print(test)
for test in ax.get_ymajorticklabels():
print(test)
ax.set_rlabel_position(50)
plt.savefig('radarchartingmalshare.pdf',bbox_inches='tight')
fig.clf()
plt.clf()
One solution is to set yticks and yticklabels manually
right_end = 51.81
ax.set_ylim(0,np.log10(right_end / init_mag))
y_ticks = np.linspace(0,np.log10(right_end/init_mag),10)
ax.set_yticks(y_ticks)
y_ticklabels = ['%.2f' % (init_mag*10**x) if x !=0 else '0.00' for x in ax.get_yticks()]
ax.set_yticklabels(y_ticklabels)
With this manually set ticks and the labels
import numpy as np
from matplotlib import pyplot as plt
fig = plt.figure(figsize=(8, 8));
ax = fig.add_subplot(111, polar=True)
np.seterr(divide = 'warn')
sample = [35.417256011315416,0.028288543140028287,1.3578500707213579,3.3663366336633667,
0.8203677510608205,35.445544554455445,3.3946251768033946,19.46251768033946,0.7072135785007072,]
get_mag = lambda x: 10**min(np.floor(np.log10(x)))
init_mag = get_mag(sample)
sample = np.array(sample) / get_mag(sample)
dat = np.log10(sample)
N = len(sample)
theta = np.arange(0, 2 * np.pi, 2 * np.pi / N)
bars = ax.bar(theta, dat, width=0.4, color = 'deepskyblue')
ax.set_xticks(theta)
ax.xaxis.grid(False)
right_end = 51.81
ax.set_ylim(0,np.log10(right_end / init_mag))
ax.yaxis.grid(True)
y_ticks = np.linspace(0,np.log10(right_end/init_mag),10)
ax.set_yticks(y_ticks)
y_ticklabels = ['%.2f' % (init_mag*10**x) if x !=0 else '0.00' for x in ax.get_yticks()]
ax.set_yticklabels(y_ticklabels)
ax.tick_params(axis='y',colors='darkviolet')
plt.show()

How can I have a colormap legend for different circle labels

I am drawing different circles with Matplotlib. Each circle has a label, and each label has a colour. What can I do to have a colourmap legend for these different labels?
I have tried a lot of solutions online, including the most naive one by just adding plt.colorbar(), which I will get the error
RuntimeError('No mappable was found to use for colorbar')
Here is my complete code. It's a little bit long. Please note that the key part just starts from if labels is None:. I just include everything for completeness.
def plot_gaussian_circles(loc_list, scale_list, save_path=None, sigma_coe=3, num_to_plot=300, labels=None):
mu_x_max = -float('inf')
mu_y_max = -float('inf')
mu_x_min = float('inf')
mu_y_min = float('inf')
color_idx = 0
rvs = []
lim_loc_list = loc_list[:num_to_plot]
lim_scale_list = scale_list[:num_to_plot]
for a_mu_, a_sigma_ in zip(lim_loc_list, lim_scale_list):
a_mu = a_mu_.squeeze()
a_sigma_ = a_sigma_.squeeze()
if not type(a_sigma_) is np.ndarray:
a_sigma_ = a_sigma_.numpy()
radius = sigma_coe * np.max(a_sigma_)
a_mu_x = a_mu[0]
a_mu_y = a_mu[1]
if (a_mu_x + radius) >= mu_x_max:
mu_x_max = a_mu_x + radius
if (a_mu_x - radius) <= mu_x_min:
mu_x_min = a_mu_x - radius
if (a_mu_y + radius) >= mu_y_max:
mu_y_max = a_mu_y + radius
if (a_mu_y - radius) <= mu_y_min:
mu_y_min = a_mu_y - radius
if labels is None:
rv = plt.Circle(a_mu, radius, fill=False, clip_on=False)
else:
colors = cm.rainbow(np.linspace(0, 1, len(set(labels))))
rv = plt.Circle(a_mu, radius, color=colors[labels[color_idx]], fill=False, clip_on=False)
rvs.append(rv)
color_idx = (color_idx + 1)
fig, ax = plt.subplots()
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
axes = plt.gca()
axes.set_xlim([mu_x_min - 1, mu_x_max + 1])
axes.set_ylim([mu_y_min - 1, mu_y_max + 1])
for rv in rvs:
ax.add_artist(rv)
if not(labels is None):
# plt.legend(colors, list(range(len(set(labels)))))
plt.colorbar()
if save_path is None:
plt.plot()
plt.show()
# plt.savefig('plotcircles_test.png')
else:
plt.savefig(save_path, dpi=200)
The image here is currently what I am getting, while I wish to have a legend of the colormap.
I found doing this will have the colour for the circles. Thanks ImportanceOfBeingErnest's comment for suggesting PatchCollection.
p = PatchCollection(rvs, cmap=cm.jet, alpha=0.4)
p.set_array(labels)
ax.add_collection(p)
fig.colorbar(p, ax=ax)

AttributeError: 'Axes' object has no attribute 'get_proj' in matplotlib

I am making the representation of a polynom function.
I have an error in a matplotlib code and cannot understand where it is coming from. any advice is welcome.
I tried already Gtk3agg but nothing changed.
Below is the failure code.
For any reason 'get_proj' dont work here for creating labels.
And: when I use ax.get_proj() instead,
a) all labels appear bottom left
b) not all labels appear at bottom left (all points are identified by the cursor bot the labels are not written at the bottom left).
The final project will be (few things still to be done):
- on button -> labelling with coordinate appear at each cursor movement (temporary)
- click right button, the labels will be persistent till button clear is clicked
- off button -> no labelling appear
My feeling: the 3x button creation is messing anything up.
# -*- coding: utf-8 -*-
import matplotlib as mpl
from mpl_toolkits.mplot3d.proj3d import proj_transform
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
import numpy as np
mpl.use('tkagg')
def distance(point, event):
plt.sca(ax) # <------------------ introduce this one !!!!!!!!!!!!!!!!!!!!!!!!!!!
x2, y2, _ = proj_transform(point[0], point[1], point[2], plt.gca().get_proj())
x3, y3 = ax.transData.transform((x2, y2))
return np.sqrt ((x3 - event.x)**2 + (y3 - event.y)**2)
def calcClosestDatapoint(X, event):
distances = [distance(X[i, 0:3], event) for i in range(Sol)]
return np.argmin(distances)
#
def annotatePlot(X, index):
global last_mark, generated_labels
if activated_labelling:
x2, y2, _ = proj_transform(X[index, 0], X[index, 1], X[index, 2], ax.get_proj())
last_mark = plt.annotate(generated_labels[index],
xy = (x2, y2), xytext = (-20, 20), textcoords = 'offset points', ha = 'right', va = 'bottom',
bbox = dict(boxstyle = 'round,pad=0.5', fc = 'yellow', alpha = 0.5),
arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0'))
fig.canvas.draw()
#
def onMouseMotion(event):
global Coord
if activated_labelling:
closestIndex = calcClosestDatapoint(Coord, event)
last_mark.remove()
annotatePlot(Coord, closestIndex)
def show_on(event):
global activated_labelling, last_mark,pid,mid
if activated_labelling == False:
activated_labelling = True
x2, y2, _ = proj_transform(Coord[0,0], Coord[0,1], Coord[0,2], ax.get_proj())
last_mark = plt.annotate("3D measurement on " + generated_labels[0],
xy = (x2, y2), xytext = (-20, 20), textcoords = 'offset points', ha = 'right', va = 'bottom',
bbox = dict(boxstyle = 'round,pad=0.5', fc = 'yellow', alpha = 0.5),
arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0'))
mid = fig.canvas.mpl_connect('motion_notify_event', onMouseMotion)
#
def show_off(event):
global activated_labelling
'''
deactivate the persistent XYZ position labels at the grafic
'''
if activated_labelling:
activated_labelling = False
last_mark.remove()
fig.canvas.draw()
fig.canvas.mpl_disconnect(mid)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
#ax = fig.gca(projection='3d')
activated_labelling = False
Wide = 100
Minimum = -50
ScanLimit = 3 # searching between o and 3; 4 and 5 are no solutions
Search = 45
Coord=[]
values=[]
generated_labels = []
#
XMin = 0
XMax = 0
YMin = 0
YMax = 0
ZMin = 0
ZMax = 0
# count the solutions found in the scan area defined above
Sol=0
for i in range(Wide+1):
for j in range(Wide+1):
for k in range(Wide+1):
########################################################################
########################################################################
####
#### THIS IS THE POLYNOM TO BE REPRESENTED
####
param_dens = ((i+Minimum)**3)+((j+Minimum)**3)+((k+Minimum)**3) -Search
if abs(param_dens) <= abs(ScanLimit):
Coord.append([i+Minimum,j+Minimum,k+Minimum])
if ScanLimit !=0:
values.append([abs(param_dens)])
labelling = "value {}\nin X:{} Y:{} Z:{}".format(Search+param_dens,i+Minimum,j+Minimum,k+Minimum)
generated_labels.append(labelling)
print(labelling+"\n")
# increase the number indicating the solutions found
Sol +=1
# for centering the window
if XMin > i+Minimum:
XMin = i+Minimum
if YMin > j+Minimum:
YMin = j+Minimum
if ZMin > k+Minimum:
ZMin = k+Minimum
if XMax < i+Minimum:
XMax = i+Minimum
if YMax < j+Minimum:
YMax = j+Minimum
if ZMax < k+Minimum:
ZMax = k+Minimum
print('######################################################')
print('## statistics / move this to a parallel search engine?')
print('## search ')
print("## total solution %d for searching center %d" % (Sol,Search))
print("## from %d to %d" % (Search-ScanLimit,Search+ScanLimit))
print("## from %d to %d" % (Minimum,Wide+Minimum))
print('##')
print('#######################################################')
#
values = np.array(values, dtype='int64')
Coord = np.array(Coord, dtype='int64')
#
if ScanLimit !=0:
cmap = plt.cm.jet # define the colormap
# extract all colors from the .jet map
cmaplist = [cmap(i) for i in range(cmap.N)]
# force the first color entry to be black
cmaplist[0] = (0, 0, 0, 1.0)
# create the new map
cmap = mpl.colors.LinearSegmentedColormap.from_list('Custom cmap', cmaplist, cmap.N)
# define the bins and normalize
bounds = np.linspace(0, ScanLimit, ScanLimit+1)
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
# create a second axes for the colorbar
ax2 = fig.add_axes([0.95, 0.1, 0.03, 0.8])
cb = mpl.colorbar.ColorbarBase(ax2, cmap=cmap, norm=norm,
spacing='proportional', ticks=bounds, boundaries=bounds, format='%1i')
#
ax.set_xlim3d(XMin-5, XMax+5)
ax.set_ylim3d(YMin-5, YMax+5)
ax.set_zlim3d(ZMin-5, ZMax+5)
#
ax.set_xlabel('X X')
ax.set_ylabel('Y Y')
ax.set_zlabel('Z Z')
ax.set_aspect(aspect=1)
# extract the scatterplot drawing in a separate function so we ca re-use the code
def draw_scatterplot():
if ScanLimit !=0:
ax.scatter3D(Coord[:,0], Coord[:,1], Coord[:,2], s=20, c=values[:,0], cmap=cmap, norm=norm)
else:
ax.scatter3D(Coord[:,0], Coord[:,1], Coord[:,2], s=20, c='green')
# draw the initial scatterplot
draw_scatterplot()
# create the "on" button, and place it somewhere on the screen
ax_on = plt.axes([0.0, 0.0, 0.1, 0.05])
button_on = Button(ax_on, 'on')
#
ax_off = plt.axes([0.12, 0.0, 0.1, 0.05])
button_off = Button(ax_off, 'off')
#
#ax_off = plt.axes([0.24, 0.0, 0.1, 0.05])
#button_off = Button(ax_off, 'off')
# link the event handler function to the click event on the button
button_on.on_clicked(show_on)
button_off.on_clicked(show_off)
#fig.colorbar(img)
plt.show()
Traceback (most recent call last):
File "C:\Program Files\Anaconda3\lib\site-packages\matplotlib\cbook\__init__.py", line 388, in process
proxy(*args, **kwargs)
File "C:\Program Files\Anaconda3\lib\site-packages\matplotlib\cbook\__init__.py", line 228, in __call__
return mtd(*args, **kwargs)
File "C:/Users/../Desktop/heat.py", line 137, in onClick
closestIndex,LowestDistance = calcClosestDatapoint(Coord, event)
File "C:/Users/../Desktop/heat.py", line 50, in calcClosestDatapoint
distances = [distance(X[i, 0:3], event) for i in range(Sol)]
File "C:/Users/../Desktop/heat.py", line 50, in <listcomp>
distances = [distance(X[i, 0:3], event) for i in range(Sol)]
File "C:/Users/../Desktop/heat.py", line 35, in distance
x2, y2, _ = proj_transform(point[0], point[1], point[2], plt.gca().get_proj())
AttributeError: 'Axes' object has no attribute 'get_proj'

How to draw polygons around 3D coordinates while also wrapping round the box?

I have points plotted in 3D space, with four polygons that slice through the data cube at angles to the y and x axes.
I would like to, for each black data point in the box, work out the coordinates of the vertices of a square centred on the data point. Using these coordinates I can draw a polgyon, in the same way that I am doing now. The dimensions of this square would need to be the same as the width value defined on line 7. The square drawn must be inclined so it lies exactly on the existing plotted plane.
Does anybody know the best way to approach this? The other difficult thing would be that, if the square leaves the box, it should wrap round the other side of the box. The box can be stacked horizontallyand vertically with identical boxes, tiling infinitely.
My code can be found belw (sorry it's messy):
import matplotlib.pyplot as pyplot
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
angle = np.arctan2(1,4)
xangle = np.arctan2(1,4)
width = 100/np.cos(angle)
print 'angle:', angle*(180/np.pi)
print 'xangle:', xangle*(180/np.pi)
print 'width:', width
x1 = [0, 0, 0, 0, 50, 50, 50, 50]
y1 = [50,50,50,50,50,50,50,50]
z1 = [12.5,37.5,62.5,87.5,25,50,75,0]
x2 = [0,0,0,0,0,0,0,0,50,50,50,50,50,50,50,50]
y2 = [0,50,0,50,0,50,0,50,0,50,0,50,0,50,0,50]
z2 = [0,12.5,25,37.5,50,62.5,75,87.5,12.5,25,37.5,50,62.5,75,87.5,0]
fig = pyplot.figure()
ax = fig.add_subplot(111, projection = '3d')
ax.set_xlim(0,100)
ax.set_ylim(0,100)
ax.set_zlim(0,100)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
#ax.view_init(elev=90, azim=90)
#ax.scatter(x1, y1, z1, zdir='z', s=20, c='g')
ax.scatter(x2, y2, z2, zdir='z', s=20, c='r') #THESE ARE RICHARD'S COORDINATES notice how they do not lie on the plane
xa = [0,100,100,0]
ya = [0,0,100,100]
za = [0,-6.25,18.75,25]
verts = [zip(xa,ya,za)]
ax.add_collection3d(Poly3DCollection(verts))
xb = [0,100,100,0]
yb = [0,0,100,100]
zb = [25,-6.25+25,18.75+25,50]
verts = [zip(xb,yb,zb)]
ax.add_collection3d(Poly3DCollection(verts))
xc = [0,100,100,0]
yc = [0,0,100,100]
zc = [50,-6.25+25*2,18.75+25*2,75]
verts = [zip(xc,yc,zc)]
ax.add_collection3d(Poly3DCollection(verts))
xd = [0,100,100,0]
yd = [0,0,100,100]
zd = [75,-6.25+25*3,18.75+25*3,100]
verts = [zip(xd,yd,zd)]
ax.add_collection3d(Poly3DCollection(verts))
#pyplot.show()
x = [0]
y = [0]
z = [0]
for i in range(1,100):
new_x = x[(len(x)-1)] + 50
new_y = y[(len(y)-1)] + 12.5
new_z = z[(len(z)-1)]
if new_x >= 100:
new_x = new_x - 100
new_z = new_z + 6.25
if new_y >= 100:
new_y = new_y - 100
if new_z >= 100:
new_z = new_z - 100
if new_x == 0 and new_y == 0 and new_z == 0:
print 'done!', i
x.append(new_x)
y.append(new_y)
z.append(new_z)
ax.scatter(x, y, z, zdir='z', s=20, c='k', zorder=1)
pyplot.show()
Done! (Without wrapping around the box though..)
import matplotlib.pyplot as pyplot
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import random
angle = np.arctan2(1,4)
xangle = np.arctan2(1,4)
width = 100/np.cos(angle)
print 'angle:', angle*(180/np.pi)
print 'xangle:', xangle*(180/np.pi)
print 'width:', width
def totuple(a):
try:
return tuple(totuple(i) for i in a)
except TypeError:
return a
def plotSquare(ax,cx,cy,cz, yaw, pitch, diameter):
colour1 = random.randint(0,255)/256.0
colour2 = random.randint(0,255)/256.0
colour3 = random.randint(0,255)/256.0
centre = np.array([cx,cy,cz])
radius = diameter/2
#0,0,0 to 100,25,125 diff
#100,25,125 /2
#50,12.5,62.5 /50
#1.0,0.25,1.25
d1offset = np.array([np.cos(pitch)*radius,(np.cos(yaw)*radius)+(np.sin(pitch)*radius),np.sin(yaw)*radius])
c1 = centre - d1offset
c2 = centre + d1offset
#100,0,25 to 0,25,100 diff
#-100,25,75 /2
#-50,12.5,37.5 /50
#-1.0,0.25,0.75
d2offset = np.array([-np.cos(yaw)*radius,(np.cos(pitch)*radius)-(np.sin(yaw)*radius),np.sin(pitch)*radius])
c3 = centre - d2offset
c4 = centre + d2offset
verts = [[totuple(c1),totuple(c3),totuple(c2),totuple(c4)]]
ax.add_collection3d(Poly3DCollection(verts, facecolors=[colour1,colour2,colour3]))
x1 = [0, 0, 0, 0, 50, 50, 50, 50]
y1 = [50,50,50,50,50,50,50,50]
z1 = [12.5,37.5,62.5,87.5,25,50,75,0]
x2 = [0,0,0,0,0,0,0,0,50,50,50,50,50,50,50,50]
y2 = [0,50,0,50,0,50,0,50,0,50,0,50,0,50,0,50]
z2 = [0,12.5,25,37.5,50,62.5,75,87.5,12.5,25,37.5,50,62.5,75,87.5,0]
fig = pyplot.figure()
ax = fig.add_subplot(111, projection = '3d')
ax.set_xlim(0,100)
ax.set_ylim(0,100)
ax.set_zlim(0,100)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
#ax.view_init(elev=90, azim=90)
#ax.scatter(x1, y1, z1, zdir='z', s=20, c='g')
ax.scatter(x2, y2, z2, zdir='z', s=20, c='r') #EXISTING COORDINATES notice how they do not lie on the plane
xa = [0,100,100,0]
ya = [0,0,100,100]
za = [0,-6.25,18.75,25]
verts = [zip(xa,ya,za)]
ax.add_collection3d(Poly3DCollection(verts))
xb = [0,100,100,0]
yb = [0,0,100,100]
zb = [25,-6.25+25,18.75+25,50]
verts = [zip(xb,yb,zb)]
ax.add_collection3d(Poly3DCollection(verts))
xc = [0,100,100,0]
yc = [0,0,100,100]
zc = [50,-6.25+25*2,18.75+25*2,75]
verts = [zip(xc,yc,zc)]
ax.add_collection3d(Poly3DCollection(verts))
xd = [0,100,100,0]
yd = [0,0,100,100]
zd = [75,-6.25+25*3,18.75+25*3,100]
verts = [zip(xd,yd,zd)]
ax.add_collection3d(Poly3DCollection(verts))
x = [0]
y = [0]
z = [0]
for i in range(1,100):
new_x = x[(len(x)-1)] + 50
new_y = y[(len(y)-1)] + 12.5
new_z = z[(len(z)-1)]
if new_x >= 100:
new_x = new_x - 100
new_z = new_z + 6.25
#new_y = new_y + (50-12.5)
if new_y >= 100:
new_y = new_y - 100
if new_z >= 100:
new_z = new_z - 100
if new_x == 0 and new_y == 0 and new_z == 0:
print 'done!', i
x.append(new_x)
y.append(new_y)
z.append(new_z)
ax.scatter(x, y, z, zdir='z', s=20, c='k', zorder=1)
storedcoordinates = zip(x,y,z)
for x,y,z in storedcoordinates:
plotSquare(ax,x,y,z,xangle,angle, width/2)
pyplot.show()

Matplotlib multiple animate multiple lines

I have been researching on how to animate multiple lines for a flight path. The object it that I read multiple GPS files time sync them them animate each path with respect to time. I found how to animate one line using append in the animate functions. Now I need to add a second and third for as many files are imported.
I know the problem is somewhere in how I perform the set_data with the lines. I ahve seen multiple example but I do not understand what structure is required to set up multiple lines. Yes I am a newbie.
fig = plt.figure()
ax1 = plt.axes(xlim=(-108, -104), ylim=(31,34))
line, = ax1.plot([], [], lw=2)
plt.xlabel('Longitude')
plt.ylabel('Latitude')
plotlays, plotcols = [2], ["black","red"]
lines = []
for index in range(2):
lobj = ax1.plot([],[],lw=2,color=plotcols[index])[0]
lines.append(lobj)
def init():
for line in lines:
line.set_data([],[])
return lines
x1,y1 = [],[]
x2,y2 = [],[]
frame_num = len(gps_data[0])
# animation function. This is called sequentially
def animate(i):
x = gps_data[0][i,3]
y = gps_data[0][i,2]
x1.append(x)
y1.append(y)
x = gps_data[1][i,3]
y = gps_data[1][i,2]
x2.append(x)
y2.append(y)
#X = np.array(x1, x2)
#Y = np.array(y1, y2)
#for index in range(0,1):
for lnum,line in enumerate(lines):
line.set_data([x1,y1, x2,y2])
return lines,
# call the animator. blit=True means only re-draw the parts that have changed.
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=frame_num, interval=1, blit=True)
plt.show()
The Matplotlib documentation for the line2d artist explains how set_data works. It "ACCEPTS: 2D array (rows are x, y) or two 1D arrays." It also works with lists. You've given it a four element list instead. You need to set the x and y data of each line separately. I've included an example with fake data below.
import matplotlib.pyplot as plt
from matplotlib import animation
from numpy import random
fig = plt.figure()
ax1 = plt.axes(xlim=(-108, -104), ylim=(31,34))
line, = ax1.plot([], [], lw=2)
plt.xlabel('Longitude')
plt.ylabel('Latitude')
plotlays, plotcols = [2], ["black","red"]
lines = []
for index in range(2):
lobj = ax1.plot([],[],lw=2,color=plotcols[index])[0]
lines.append(lobj)
def init():
for line in lines:
line.set_data([],[])
return lines
x1,y1 = [],[]
x2,y2 = [],[]
# fake data
frame_num = 100
gps_data = [-104 - (4 * random.rand(2, frame_num)), 31 + (3 * random.rand(2, frame_num))]
def animate(i):
x = gps_data[0][0, i]
y = gps_data[1][0, i]
x1.append(x)
y1.append(y)
x = gps_data[0][1,i]
y = gps_data[1][1,i]
x2.append(x)
y2.append(y)
xlist = [x1, x2]
ylist = [y1, y2]
#for index in range(0,1):
for lnum,line in enumerate(lines):
line.set_data(xlist[lnum], ylist[lnum]) # set data for each line separately.
return lines
# call the animator. blit=True means only re-draw the parts that have changed.
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=frame_num, interval=10, blit=True)
plt.show()
fig, ax1 = plt.subplots(figsize=(20,10))
plt.xticks()
ax1.set_xlabel("time")
ax1.set_ylabel("amp")
ax1.grid(True)
ox = get_data_o("/tmp/bf_ox.npy")
oy = get_data_o("/tmp/bf_oy.npy")
graphic_data = []
graphic_data.append(ax1.plot(ox, oy,"b-")[0])
sx = get_data_o("/tmp/bf_sx.npy")
i = 1
for p in sp.procs:
c = get_c(i)
sy = get_data_o("/tmp/bf_" + p + ".npy")
graphic_data.append(ax1.plot(sx, sy,c + "-")[0])
i = i + 1
def animate(i):
print ("frame")
ox = get_data_o("/tmp/bf_ox.npy")
oy = get_data_o("/tmp/bf_oy.npy")
i = 0
graphic_data[i].set_xdata(ox)
graphic_data[i].set_ydata(oy)
i = 1
sx = get_data_o("/tmp/bf_sx.npy")
for p in sp.procs:
sy = get_data_o("/tmp/bf_" + p + ".npy")
graphic_data[i].set_xdata(sx)
graphic_data[i].set_ydata(sy)
i = i + 1
return graphic_data
ani = animation.FuncAnimation(fig, animate, interval=2000, blit=True)
plt.show()