在使用Python的Matplotlib绘制图表时遇到的颜色问题。

huangapple go评论64阅读模式
英文:

Colors problem in plotting figure with matplotlib in python

问题

我试图绘制一个双部分图来突出两个排名之间的差异。我通过用彩色箭头将左侧列表中的城市与右侧列表中的相同城市相连接来实现这一目标。颜色应与排名差异成比例。

这是一个最小工作示例:

import matplotlib.pyplot as plt

# 示例数据
cities = ['City A', 'City B', 'City C', 'City D', 'City E',
          'City F', 'City G', 'City H', 'City I', 'City J']
genepy_rank = [3, 1, 4, 2, 5, 8, 7, 10, 9, 6]
fitness_rank = [7, 9, 2, 5, 4, 6, 3, 1, 8, 10]

# 计算排名差异
diff_rank = [genepy - fitness for genepy, fitness in zip(genepy_rank, fitness_rank)]

# 绘制图形
fig, ax = plt.subplots()
for i, city in enumerate(cities):
    x = [genepy_rank[i], fitness_rank[i]]
    y = [i, i]
    color = diff_rank[i]
    ax.plot(x, y, color=color, marker='o')
    ax.annotate(city, (x[0], y[0]), 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'))
ax.set_xlim(0, 11)
ax.set_ylim(-1, 11)
ax.set_yticks([i for i in range(len(cities))])
ax.set_yticklabels(cities)
ax.spines['left'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.yaxis.tick_right()
ax.yaxis.set_label_position("right")
plt.show()

问题是这会导致错误退出:ValueError:-4不是一个有效的颜色值,我理解这个问题。是否有一种方法可以确定颜色网格并基于diff_rank分配颜色给箭头?

谢谢。

英文:

I am trying to plot a bipartite graph to highlight the differences between two rankings. I am doing so by connecting the city in the left list to the same city on the right list with a colored arrow. The color should be proportional to the difference in rankings.

Here is a MWE:

import matplotlib.pyplot as plt

# Sample data
cities = ['City A', 'City B', 'City C', 'City D', 'City E',
          'City F', 'City G', 'City H', 'City I', 'City J']
genepy_rank = [3, 1, 4, 2, 5, 8, 7, 10, 9, 6]
fitness_rank = [7, 9, 2, 5, 4, 6, 3, 1, 8, 10]

# Calculate the difference in ranking
diff_rank = [genepy - fitness for genepy, fitness in zip(genepy_rank, fitness_rank)]

# Plot the graph
fig, ax = plt.subplots()
for i, city in enumerate(cities):
    x = [genepy_rank[i], fitness_rank[i]]
    y = [i, i]
    color = diff_rank[i]
    ax.plot(x, y, color=color, marker='o')
    ax.annotate(city, (x[0], y[0]), 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'))
ax.set_xlim(0, 11)
ax.set_ylim(-1, 11)
ax.set_yticks([i for i in range(len(cities))])
ax.set_yticklabels(cities)
ax.spines['left'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.yaxis.tick_right()
ax.yaxis.set_label_position("right")
plt.show()

The problem is that this exits with an error: ValueError: -4 is not a valid value for color which I understand. Is there a way to determine a color grid and assign a color to the arrows based on diff_rank?

Thank you

答案1

得分: 0

不要指定颜色,为什么不使用颜色映射呢?

如果你想要显示颜色条(就像我所做的),请记住 plt.plot 不提供所需的 ScalarMappable 以实例化颜色条,所以你必须提供一个。

import matplotlib.pyplot as plt
from matplotlib.cm import ScalarMappable
from matplotlib.colors import BoundaryNorm

# 示例数据
cities = ['City A', 'City B', 'City C', 'City D', 'City E',
          'City F', 'City G', 'City H', 'City I', 'City J']
genepy_rank = [3, 1, 4, 2, 5, 8, 7, 10, 9, 6]
fitness_rank = [7, 9, 2, 5, 4, 6, 3, 1, 8, 10]

# 计算排名差异
diff_rank = [genepy - fitness for genepy, fitness in zip(genepy_rank, fitness_rank)]
dmin, dmax = min(diff_rank), max(diff_rank)

boundaries = [dmin-0.5]+[d+0.5 for d in range(dmin, dmax+1)]
cm = plt.get_cmap('Spectral')
norm = BoundaryNorm(boundaries, 256)

print(type(norm))
# 绘制图表
fig, ax = plt.subplots(layout='constrained')
for i, city in enumerate(cities):
    x = [genepy_rank[i], fitness_rank[i]]
    y = [i, i]
    color = cm(norm(diff_rank[i]))
    ax.plot(x, y,  color=color, marker='o')
    ax.annotate(city, (x[0], y[0]), 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'))
ax.set_xlim(0, 11)
ax.set_ylim(-1, 11)
cb = plt.colorbar(ScalarMappable(norm, cm), ax=ax)
cb.set_ticks(range(dmin, dmax+1))
cb.set_ticklabels(['%+2d'%t for t in range(dmin, dmax+1)])
cb.setlabel('排名差异(genepy - fitness)')
plt.show()
英文:

Instead of specifying a color, why don't you use a colormap?

If you want to show also a colorbar (as I did) remember that plt.plot doesn't provide the ScalarMappable that's necessary to instantiate a Colorbar, so you have to provide one.

在使用Python的Matplotlib绘制图表时遇到的颜色问题。

import matplotlib.pyplot as plt
from matplotlib.cm import ScalarMappable
from matplotlib.colors import BoundaryNorm

# Sample data
cities = ['City A', 'City B', 'City C', 'City D', 'City E',
          'City F', 'City G', 'City H', 'City I', 'City J']
genepy_rank = [3, 1, 4, 2, 5, 8, 7, 10, 9, 6]
fitness_rank = [7, 9, 2, 5, 4, 6, 3, 1, 8, 10]

# Calculate the difference in ranking
diff_rank = [genepy - fitness for genepy, fitness in zip(genepy_rank, fitness_rank)]
dmin, dmax = min(diff_rank), max(diff_rank)

boundaries = [dmin-0.5]+[d+0.5 for d in range(dmin, dmax+1)]
cm = plt.get_cmap('Spectral')
norm = BoundaryNorm(boundaries, 256)

print(type(norm))
# Plot the graph
fig, ax = plt.subplots(layout='constrained')
for i, city in enumerate(cities):
    x = [genepy_rank[i], fitness_rank[i]]
    y = [i, i]
    color = cm(norm(diff_rank[i]))
    ax.plot(x, y,  color=color, marker='o')
    ax.annotate(city, (x[0], y[0]), 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'))
ax.set_xlim(0, 11)
ax.set_ylim(-1, 11)
cb = plt.colorbar(ScalarMappable(norm, cm), ax=ax)
cb.set_ticks(range(dmin, dmax+1))
cb.set_ticklabels(['%+2d'%t for t in range(dmin, dmax+1)])
cb.setlabel('Ranking Difference (genepy -fitness)')
plt.show()

I have to say that I do not think this is a good way to show your data (even if it could be the best one, I don't know…).


Maybe this is better,

在使用Python的Matplotlib绘制图表时遇到的颜色问题。

huangapple
  • 本文由 发表于 2023年2月8日 17:20:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75383559.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定