我使用的是python-3.x,我想找到一种方法来停止行右侧重叠的图例,如下面的图片所示:
我正在尝试使其看起来类似于下图: -(请注意,此图是使用图片编辑器修改的,只是为了阐明我想要的内容)
我尝试了很多方法,但是没有一种方法可以解决我的问题,例如注释。在我的情况下,如何停止图例文本在matplotlib中的重叠?
这是我正在使用的代码:(所有使用的值仅是示例)
data_1 = np.array([[0, 5, 3, 2 , 4, 7.7], [1, 1.5, 9, 7 , 8, 8], [2, 3, 3, 7 , 3, 3], [0, 5, 6, 12,4 , 3],[3, 5, 6, 10 ,2 , 6]])
df = pd.DataFrame({'111': data_1[0], '222': data_1[1], '333': data_1[2], '444': data_1[3], '555': data_1[4]})
# Graphing
#df.plot()
# 1. The color is a nice red / blue / green which is different from the primary color RGB
c = plt.get_cmap('Set1').colors
plt.rcParams['axes.prop_cycle'] = cycler(color = c)
fig, ax = plt.subplots(figsize = (7, 5))
# 2. Remove the legend
# 3. Make the line width thicker
df.plot(ax = ax, linewidth = 3, legend = False)
# 4. Display y-axis label
# 5. Change the display range of x-axis and y-axis
x_min, x_max = 0, 5
y_min, y_max = 0, 13
ax.set(ylim = (y_min, y_max), xlim = (x_min, x_max + 0.03))
# 6. Specify font size collectively
plt.rcParams["font.size"] = 14
# 7. Display graph title, X axis, Y axis name (label), grid line
plt.title("title")
plt.xlabel("x")
plt.ylabel("y")
plt.grid(True)
# 8. Remove the right and top frame
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(True)
# 9. Show index to the right of the plot instead of the normal legend
for i, name in enumerate(df.columns.values):
ax.text(x_max + 0.03, ax.lines[i].get_data()[1][-1], name, color = f'C{i}', va = 'center')
plt.savefig('plot_lines.png', dpi = 300 ,bbox_inches = 'tight')
plt.show()
有什么想法吗?
答案 0 :(得分:0)
这可能被认为是matplotlib
历史上最严重的黑客攻击,但至少就您当前的示例而言,这是我刚刚提出的。这还不是完美的,如果没有用,我很乐意删除它。但是,由于我花了一些时间去做,所以我想与您分享。
这个想法是对y值进行排序,然后使用重新缩放因子添加一个偏移量,其中将橙色曲线的索引的偏移量手动设置为0(第二值按升序排列为第三值),这就是{{ 1}}
(i-2)
答案 1 :(得分:0)
this question的答案应适合您的情况:
该想法是生成具有与数据点和相关标签点一样多的节点的图形。您只希望标签节点展开。您可以使用network.spring_layout()
图来完成此操作(请参见文档here)。
为清楚起见,随附的代码实现了功能spring_labels()
。兴趣点是
hint
(类似于 array ):某些数据点的y坐标完全相同,因此图形会将相关标签散布在同一位置。您可以使用hint
关键字参数为每个数据点赋予不同的值,以提高差异性(这里我倒数第二点)spread
( float ):控制节点分布的距离;应该手动设置该值以优化结果shift
( float ):标签x坐标在x方向上的位移。import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import networkx as nx
from cycler import cycler
def spring_labels(ax, x, y, labels, spread=.03, shift=.1, hint=None, colors=None):
if hint is None:
hint = y
if colors is None:
colors = ['C{}' for i in range(len(y))]
# Create graph
graph = nx.DiGraph()
# node_labels = labels
node_data = ['data_{}'.format(l) for l in labels]
graph.add_nodes_from(node_data + labels)
graph.add_edges_from(zip(node_data, labels))
# Initialize position
graph_init = dict()
for yi, yh, nd, nl in zip(y, hint, node_data, labels):
graph_init[nd] = (x, yi)
graph_init[nl] = (x + shift, yi + (yi - yh) * .1)
# Draw spring-force graph
positions = nx.spring_layout(graph, pos=graph_init, fixed=node_data, k=spread)
for label in labels:
positions[label][0] = x + shift
# colors = plt.rcParams['axes.color_cycle']
# print(colors)
for (data, label), color in zip(graph.edges, colors):
ax.plot([positions[label][0], positions[data][0]],
[positions[label][1], positions[data][1]],
color=color, clip_on=False)
ax.text(*positions[label], label, color=color)
data_1 = np.array([[0, 5, 3, 2, 4, 7.7], [1, 1.5, 9, 7, 8, 8], [
2, 3, 3, 7, 3, 3], [0, 5, 6, 12, 4, 3], [3, 5, 6, 10, 2, 6]])
df = pd.DataFrame({'111': data_1[0], '222': data_1[1], '333': data_1[
2], '444': data_1[3], '555': data_1[4]})
# Graphing
# df.plot()
# 1. The color is a nice red / blue / green which is different from the
# primary color RGB
c = plt.get_cmap('Set1').colors
plt.rcParams['axes.prop_cycle'] = cycler(color=c)
fig, ax = plt.subplots(figsize=(7, 5))
# 2. Remove the legend
# 3. Make the line width thicker
df.plot(ax=ax, linewidth=3, legend=False)
# 4. Display y-axis label
# 5. Change the display range of x-axis and y-axis
x_min, x_max = 0, 5
y_min, y_max = 0, 13
ax.set(ylim=(y_min, y_max), xlim=(x_min, x_max + 0.03))
# 6. Specify font size collectively
plt.rcParams["font.size"] = 14
# 7. Display graph title, X axis, Y axis name (label), grid line
plt.title("title")
plt.xlabel("x")
plt.ylabel("y")
plt.grid(True)
# 8. Remove the right and top frame
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(True)
# 9. Show index to the right of the plot instead of the normal legend
ys_hint = [a.get_data()[1][-2] for a in ax.lines]
ys_max = [a.get_data()[1][-1] for a in ax.lines]
spring_labels(ax, x_max, ys_max, df.columns.values, shift=.2, hint=ys_hint, colors=c)
plt.savefig('plot_lines.png', dpi=300, bbox_inches='tight')