在 Line2d 中更改线条颜色 - Python GIF
Changing line color in Line2d - Python GIF
我创建了一个算法来解决 TSP 问题。我想以显示行进距离的 GIF 形式呈现结果。为此,我使用 Matplotlib 库中的 line2d。每次汽车到达起点,我都想改变线条的颜色。我目前正在为此使用 line2d.set_color () 函数。不幸的是,它会导致整条道路的颜色发生变化。我的目标是在任何给定时刻更改颜色,同时保持以前的颜色。你能帮我解决这个问题吗?
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random
from gurobipy import Model, GRB, quicksum
from matplotlib import collections as mc
rnd = np.random
rnd.seed()
n = 20 # numbre of clients
xc = rnd.rand(n + 1) * 200
yc = rnd.rand(n + 1) * 100
xc[0] = 100
yc[0] = 50
N = [i for i in range(1, n + 1)]
V = [0] + N
A = [(i, j) for i in V for j in V if i != j]
c = {(i, j): np.hypot(xc[i] - xc[j], yc[i] - yc[j]) for i, j in A}
Q = 30
# q = {i: random.choice([-5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) for i in N}
# q = {i: random.choice([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) for i in N}
q = {i: rnd.randint(1, 10) for i in N}
# a = [['x', xc], ['y', yc], ['Capacity', q]]
# for i in range(len(a)) :
# for j in range(len(a[i])):
# print(a[i][j], end=" ")
# print()
mdl = Model('CVRP')
x = mdl.addVars(A, vtype=GRB.BINARY)
u = mdl.addVars(N, vtype=GRB.CONTINUOUS)
mdl.modelSense = GRB.MINIMIZE
mdl.setObjective(quicksum(x[i, j] * c[i, j] for i, j in A))
mdl.addConstrs(quicksum(x[i, j] for j in V if j != i) == 1 for i in N)
mdl.addConstrs(quicksum(x[i, j] for i in V if i != j) == 1 for j in N)
mdl.addConstrs((x[i, j] == 1) >> (u[i] + q[j] == u[j])
for i, j in A if i != 0 and j != 0)
mdl.addConstrs(u[i] >= q[i] for i in N)
mdl.addConstrs(u[i] <= Q for i in N)
mdl.Params.MIPGap = 0.1
mdl.Params.TimeLimit = 30 # seconds
mdl.optimize()
active_arcs = [a for a in A if x[a].x > 0.99]
final_arcs = []
roads = 0
while len(active_arcs) != 0:
temp_arcs = [active_arcs[0]]
for i, j in temp_arcs:
temp_j = j
i2 = 0
while temp_j != 0:
for i, j in active_arcs:
if temp_j == i and temp_j != 0:
temp_arcs.append(active_arcs[i2])
temp_j = j
i2 += 1
i2 = 0
i = 0
i2 = 0
while i < len(temp_arcs):
while i2 < len(active_arcs):
if temp_arcs[i] == active_arcs[i2]:
active_arcs.pop(i2)
i2 += 1
i += 1
i2 = 0
final_i = 0
while final_i < len(temp_arcs):
final_arcs.append(temp_arcs[final_i])
final_i += 1
temp_arcs.clear()
roads += 1
plt.plot(xc[0], yc[0], c='r', marker='s')
for i in N:
if q[i] > 0:
plt.scatter(xc[i], yc[i], c='b')
else:
plt.scatter(xc[i], yc[i], c='y')
plt.show()
print('Liczba wykonanych tras: ', roads)
# for i, j in final_arcs:
# plt.plot([xc[i], xc[j]], [yc[i], yc[j]], color, zorder=0)
# if j == 0:
# if len(colors_base) != 0:
# c = random.randint(0, len(colors_base) - 1)
# color = colors_base[c]
# colors_base.pop(c)
#
# plt.show()
fig, ax = plt.subplots()
ax.set_xlim(0, 200)
ax.set_ylim(0, 100)
x_data, y_data = [], []
ln1, ln2 = [], []
ln, = plt.plot([], [], zorder=0)
colors_base = ['r', 'cyan', 'black', 'orange', 'm', 'darkorchid', 'dimgray', 'indigo', 'lawngreen', 'darkred']
ln.set_color('g')
plt.plot(xc[0], yc[0], 'r', marker='s')
for i in N:
if q[i] > 0:
plt.scatter(xc[i], yc[i], c='b')
else:
plt.scatter(xc[i], yc[i], c='y')
tmp = 0
for i, j in final_arcs:
x_data_tmp = [xc[i], xc[j]]
y_data_tmp = [yc[i], yc[j]]
x_data.append(x_data_tmp)
y_data.append(y_data_tmp)
def update(p):
ln1.append(x_data[p])
ln2.append(y_data[p])
ln.set_data(ln1, ln2)
for i, j in final_arcs:
if yc[i] == 50 and y_data[p] == [yc[i], yc[j]] and p != 0:
if len(colors_base) != 0:
color = colors_base[0]
ln.set_color(color)
colors_base.pop(0)
return ln,
ani = FuncAnimation(fig, update, frames=len(final_arcs), interval=1000)
ani.save('animation.gif', fps=3)
# ani.save('animation.mp4', fps=3)
plt.show()
收到的 gif 是这样的:
enter image description here
一种可能的解决方案:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random
from gurobipy import Model, GRB, quicksum
from matplotlib import collections as mc
rnd = np.random
rnd.seed()
n = 20 # numbre of clients
xc = rnd.rand(n + 1) * 200
yc = rnd.rand(n + 1) * 100
xc[0] = 100
yc[0] = 50
N = [i for i in range(1, n + 1)]
V = [0] + N
A = [(i, j) for i in V for j in V if i != j]
c = {(i, j): np.hypot(xc[i] - xc[j], yc[i] - yc[j]) for i, j in A}
Q = 30
# q = {i: random.choice([-5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) for i in N}
# q = {i: random.choice([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) for i in N}
q = {i: rnd.randint(1, 10) for i in N}
mdl = Model('CVRP')
x = mdl.addVars(A, vtype=GRB.BINARY)
u = mdl.addVars(N, vtype=GRB.CONTINUOUS)
mdl.modelSense = GRB.MINIMIZE
mdl.setObjective(quicksum(x[i, j] * c[i, j] for i, j in A))
mdl.addConstrs(quicksum(x[i, j] for j in V if j != i) == 1 for i in N)
mdl.addConstrs(quicksum(x[i, j] for i in V if i != j) == 1 for j in N)
mdl.addConstrs((x[i, j] == 1) >> (u[i] + q[j] == u[j])
for i, j in A if i != 0 and j != 0)
mdl.addConstrs(u[i] >= q[i] for i in N)
mdl.addConstrs(u[i] <= Q for i in N)
mdl.Params.MIPGap = 0.1
mdl.Params.TimeLimit = 30 # seconds
mdl.optimize()
active_arcs = [a for a in A if x[a].x > 0.99]
final_arcs = []
roads = 0
while len(active_arcs) != 0:
temp_arcs = [active_arcs[0]]
for i, j in temp_arcs:
temp_j = j
i2 = 0
while temp_j != 0:
for i, j in active_arcs:
if temp_j == i and temp_j != 0:
temp_arcs.append(active_arcs[i2])
temp_j = j
i2 += 1
i2 = 0
i = 0
i2 = 0
while i < len(temp_arcs):
while i2 < len(active_arcs):
if temp_arcs[i] == active_arcs[i2]:
active_arcs.pop(i2)
i2 += 1
i += 1
i2 = 0
final_i = 0
while final_i < len(temp_arcs):
final_arcs.append(temp_arcs[final_i])
final_i += 1
temp_arcs.clear()
roads += 1
fig, ax = plt.subplots()
ax.set_xlim(0, 200)
ax.set_ylim(0, 100)
x_data, y_data = [], []
ln1, ln2 = [], []
ln, = ax.plot([], [], zorder=0)
colors_base = ['r', 'cyan', 'black', 'orange', 'm', 'darkorchid', 'dimgray', 'indigo', 'lawngreen', 'darkred']
ln.set_color('g')
plt.plot(xc[0], yc[0], 'r', marker='s')
for i in N:
if q[i] > 0:
plt.scatter(xc[i], yc[i], c='b')
else:
plt.scatter(xc[i], yc[i], c='y')
# precompute each line coordinates
lines_data = []
xd, yd = [], []
for i, j in final_arcs:
xd.append(xc[i])
yd.append(yc[i])
if j == 0:
xd.append(xc[0])
yd.append(yc[0])
lines_data.append([xd, yd])
xd, yd = [], []
# add empty lines with the specified colors
lines = []
for i in range(len(lines_data)):
lines.append(ax.plot([], [], color=colors_base[i])[0])
def update(p):
global current_line, up_to_point
# reset after each animation cycle is complete
if current_line > len(lines_data) - 1:
current_line = 0
for l in lines:
l.set_data([], [])
up_to_point += 1
xd, yd = lines_data[current_line]
lines[current_line].set_data(xd[:up_to_point], yd[:up_to_point])
if len(xd[:up_to_point]) == len(xd):
current_line += 1
up_to_point = 1
# index of the line to animate
current_line = 0
# draw the current line up to the point of this index
up_to_point = 1
ani = FuncAnimation(fig, update, frames=len(final_arcs), interval=1000)
ani.save('animation.gif', fps=3)
# ani.save('animation.mp4', fps=3)
plt.show()
我创建了一个算法来解决 TSP 问题。我想以显示行进距离的 GIF 形式呈现结果。为此,我使用 Matplotlib 库中的 line2d。每次汽车到达起点,我都想改变线条的颜色。我目前正在为此使用 line2d.set_color () 函数。不幸的是,它会导致整条道路的颜色发生变化。我的目标是在任何给定时刻更改颜色,同时保持以前的颜色。你能帮我解决这个问题吗?
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random
from gurobipy import Model, GRB, quicksum
from matplotlib import collections as mc
rnd = np.random
rnd.seed()
n = 20 # numbre of clients
xc = rnd.rand(n + 1) * 200
yc = rnd.rand(n + 1) * 100
xc[0] = 100
yc[0] = 50
N = [i for i in range(1, n + 1)]
V = [0] + N
A = [(i, j) for i in V for j in V if i != j]
c = {(i, j): np.hypot(xc[i] - xc[j], yc[i] - yc[j]) for i, j in A}
Q = 30
# q = {i: random.choice([-5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) for i in N}
# q = {i: random.choice([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) for i in N}
q = {i: rnd.randint(1, 10) for i in N}
# a = [['x', xc], ['y', yc], ['Capacity', q]]
# for i in range(len(a)) :
# for j in range(len(a[i])):
# print(a[i][j], end=" ")
# print()
mdl = Model('CVRP')
x = mdl.addVars(A, vtype=GRB.BINARY)
u = mdl.addVars(N, vtype=GRB.CONTINUOUS)
mdl.modelSense = GRB.MINIMIZE
mdl.setObjective(quicksum(x[i, j] * c[i, j] for i, j in A))
mdl.addConstrs(quicksum(x[i, j] for j in V if j != i) == 1 for i in N)
mdl.addConstrs(quicksum(x[i, j] for i in V if i != j) == 1 for j in N)
mdl.addConstrs((x[i, j] == 1) >> (u[i] + q[j] == u[j])
for i, j in A if i != 0 and j != 0)
mdl.addConstrs(u[i] >= q[i] for i in N)
mdl.addConstrs(u[i] <= Q for i in N)
mdl.Params.MIPGap = 0.1
mdl.Params.TimeLimit = 30 # seconds
mdl.optimize()
active_arcs = [a for a in A if x[a].x > 0.99]
final_arcs = []
roads = 0
while len(active_arcs) != 0:
temp_arcs = [active_arcs[0]]
for i, j in temp_arcs:
temp_j = j
i2 = 0
while temp_j != 0:
for i, j in active_arcs:
if temp_j == i and temp_j != 0:
temp_arcs.append(active_arcs[i2])
temp_j = j
i2 += 1
i2 = 0
i = 0
i2 = 0
while i < len(temp_arcs):
while i2 < len(active_arcs):
if temp_arcs[i] == active_arcs[i2]:
active_arcs.pop(i2)
i2 += 1
i += 1
i2 = 0
final_i = 0
while final_i < len(temp_arcs):
final_arcs.append(temp_arcs[final_i])
final_i += 1
temp_arcs.clear()
roads += 1
plt.plot(xc[0], yc[0], c='r', marker='s')
for i in N:
if q[i] > 0:
plt.scatter(xc[i], yc[i], c='b')
else:
plt.scatter(xc[i], yc[i], c='y')
plt.show()
print('Liczba wykonanych tras: ', roads)
# for i, j in final_arcs:
# plt.plot([xc[i], xc[j]], [yc[i], yc[j]], color, zorder=0)
# if j == 0:
# if len(colors_base) != 0:
# c = random.randint(0, len(colors_base) - 1)
# color = colors_base[c]
# colors_base.pop(c)
#
# plt.show()
fig, ax = plt.subplots()
ax.set_xlim(0, 200)
ax.set_ylim(0, 100)
x_data, y_data = [], []
ln1, ln2 = [], []
ln, = plt.plot([], [], zorder=0)
colors_base = ['r', 'cyan', 'black', 'orange', 'm', 'darkorchid', 'dimgray', 'indigo', 'lawngreen', 'darkred']
ln.set_color('g')
plt.plot(xc[0], yc[0], 'r', marker='s')
for i in N:
if q[i] > 0:
plt.scatter(xc[i], yc[i], c='b')
else:
plt.scatter(xc[i], yc[i], c='y')
tmp = 0
for i, j in final_arcs:
x_data_tmp = [xc[i], xc[j]]
y_data_tmp = [yc[i], yc[j]]
x_data.append(x_data_tmp)
y_data.append(y_data_tmp)
def update(p):
ln1.append(x_data[p])
ln2.append(y_data[p])
ln.set_data(ln1, ln2)
for i, j in final_arcs:
if yc[i] == 50 and y_data[p] == [yc[i], yc[j]] and p != 0:
if len(colors_base) != 0:
color = colors_base[0]
ln.set_color(color)
colors_base.pop(0)
return ln,
ani = FuncAnimation(fig, update, frames=len(final_arcs), interval=1000)
ani.save('animation.gif', fps=3)
# ani.save('animation.mp4', fps=3)
plt.show()
收到的 gif 是这样的:
enter image description here
一种可能的解决方案:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random
from gurobipy import Model, GRB, quicksum
from matplotlib import collections as mc
rnd = np.random
rnd.seed()
n = 20 # numbre of clients
xc = rnd.rand(n + 1) * 200
yc = rnd.rand(n + 1) * 100
xc[0] = 100
yc[0] = 50
N = [i for i in range(1, n + 1)]
V = [0] + N
A = [(i, j) for i in V for j in V if i != j]
c = {(i, j): np.hypot(xc[i] - xc[j], yc[i] - yc[j]) for i, j in A}
Q = 30
# q = {i: random.choice([-5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) for i in N}
# q = {i: random.choice([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) for i in N}
q = {i: rnd.randint(1, 10) for i in N}
mdl = Model('CVRP')
x = mdl.addVars(A, vtype=GRB.BINARY)
u = mdl.addVars(N, vtype=GRB.CONTINUOUS)
mdl.modelSense = GRB.MINIMIZE
mdl.setObjective(quicksum(x[i, j] * c[i, j] for i, j in A))
mdl.addConstrs(quicksum(x[i, j] for j in V if j != i) == 1 for i in N)
mdl.addConstrs(quicksum(x[i, j] for i in V if i != j) == 1 for j in N)
mdl.addConstrs((x[i, j] == 1) >> (u[i] + q[j] == u[j])
for i, j in A if i != 0 and j != 0)
mdl.addConstrs(u[i] >= q[i] for i in N)
mdl.addConstrs(u[i] <= Q for i in N)
mdl.Params.MIPGap = 0.1
mdl.Params.TimeLimit = 30 # seconds
mdl.optimize()
active_arcs = [a for a in A if x[a].x > 0.99]
final_arcs = []
roads = 0
while len(active_arcs) != 0:
temp_arcs = [active_arcs[0]]
for i, j in temp_arcs:
temp_j = j
i2 = 0
while temp_j != 0:
for i, j in active_arcs:
if temp_j == i and temp_j != 0:
temp_arcs.append(active_arcs[i2])
temp_j = j
i2 += 1
i2 = 0
i = 0
i2 = 0
while i < len(temp_arcs):
while i2 < len(active_arcs):
if temp_arcs[i] == active_arcs[i2]:
active_arcs.pop(i2)
i2 += 1
i += 1
i2 = 0
final_i = 0
while final_i < len(temp_arcs):
final_arcs.append(temp_arcs[final_i])
final_i += 1
temp_arcs.clear()
roads += 1
fig, ax = plt.subplots()
ax.set_xlim(0, 200)
ax.set_ylim(0, 100)
x_data, y_data = [], []
ln1, ln2 = [], []
ln, = ax.plot([], [], zorder=0)
colors_base = ['r', 'cyan', 'black', 'orange', 'm', 'darkorchid', 'dimgray', 'indigo', 'lawngreen', 'darkred']
ln.set_color('g')
plt.plot(xc[0], yc[0], 'r', marker='s')
for i in N:
if q[i] > 0:
plt.scatter(xc[i], yc[i], c='b')
else:
plt.scatter(xc[i], yc[i], c='y')
# precompute each line coordinates
lines_data = []
xd, yd = [], []
for i, j in final_arcs:
xd.append(xc[i])
yd.append(yc[i])
if j == 0:
xd.append(xc[0])
yd.append(yc[0])
lines_data.append([xd, yd])
xd, yd = [], []
# add empty lines with the specified colors
lines = []
for i in range(len(lines_data)):
lines.append(ax.plot([], [], color=colors_base[i])[0])
def update(p):
global current_line, up_to_point
# reset after each animation cycle is complete
if current_line > len(lines_data) - 1:
current_line = 0
for l in lines:
l.set_data([], [])
up_to_point += 1
xd, yd = lines_data[current_line]
lines[current_line].set_data(xd[:up_to_point], yd[:up_to_point])
if len(xd[:up_to_point]) == len(xd):
current_line += 1
up_to_point = 1
# index of the line to animate
current_line = 0
# draw the current line up to the point of this index
up_to_point = 1
ani = FuncAnimation(fig, update, frames=len(final_arcs), interval=1000)
ani.save('animation.gif', fps=3)
# ani.save('animation.mp4', fps=3)
plt.show()