Matplotlib,图例符号之间的垂直间距

7

我在自定义图例时遇到了问题。我尝试了很多自定义操作,但是对于这个问题还无法理解。我希望图例中的符号(而不是标签)在间隔相等的情况下呈现。从示例中可以看到,圆圈之间的间距会随着圆圈变大而缩小。你有什么想法吗? 此外,我怎样才能添加一个颜色条(除了大小),其中小圆圈为浅红色(例如),大圆圈为蓝色(例如)。 以下是我目前的代码:

import pandas as pd
import matplotlib.pyplot as plt
from vega_datasets import data as vega_data
gap = pd.read_json(vega_data.gapminder.url)

df = gap.loc[gap['year'] == 2000]

fig, ax = plt.subplots(1, 1,figsize=[14,12])
ax=ax.scatter(df['life_expect'], df['fertility'], 
            s = df['pop']/100000,alpha=0.7, edgecolor="black",cmap="viridis")

plt.xlabel("X")
plt.ylabel("Y");
kw = dict(prop="sizes", num=6, color="lightgrey", markeredgecolor='black',markeredgewidth=2)
plt.legend(*ax.legend_elements(**kw),bbox_to_anchor=(1, 0),frameon=False,
                    loc="lower left",markerscale=1,ncol=1,borderpad=2,labelspacing=4,handletextpad=2)

plt.grid()
plt.show()

enter image description here


由于图例自动与标记相关联,我们是否可以通过设置 *kw = dict(markerscale=None...) 来改进这一点? - r-beginners
不,它没有改变任何东西... - Seji
1个回答

3

这有点棘手,但您可以测量图例元素并重新定位它们以保持固定的间距。由于像素定位,绘图后无法调整大小。

我使用“Qt5Agg”后端在PyCharm中测试了代码。在Jupyter笔记本中,分别使用%matplotlib inline%matplotlib notebook 进行测试。我不确定它是否能够在所有环境下正常工作。

请注意,ax.scatter不返回ax(与sns.scatterplot相反),而是返回创建的散点的列表。

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.transforms import IdentityTransform
from vega_datasets import data as vega_data

gap = pd.read_json(vega_data.gapminder.url)
df = gap.loc[gap['year'] == 2000]

fig, ax = plt.subplots(1, 1, figsize=[14, 12])
fig.subplots_adjust(right=0.8)
scat = ax.scatter(df['life_expect'], df['fertility'],
                  s=df['pop'] / 100000, alpha=0.7, edgecolor="black", cmap="viridis")

plt.xlabel("X")
plt.ylabel("Y")
x = 1.1
y = 0.1
is_first = True
kw = dict(prop="sizes", num=6, color="lightgrey", markeredgecolor='black', markeredgewidth=2)
handles, labels = scat.legend_elements(**kw)

inverted_transData = ax.transData.inverted()
for handle, label in zip(handles[::-1], labels[::-1]):
    plt.setp(handle, clip_on=False)
    for _ in range(1 if is_first else 2):
        plt.setp(handle, transform=ax.transAxes)
        if is_first:
            xd, yd = x, y
        else:
            xd, yd = inverted_transData.transform((x, y))
        handle.set_xdata([xd])
        handle.set_ydata([yd])
        ax.add_artist(handle)
        bbox = handle.get_window_extent(fig.canvas.get_renderer())
        y += y - bbox.y0 + 15  # 15 pixels inbetween
    x = (bbox.x0 + bbox.x1) / 2
    if is_first:
        xd_text, _ = inverted_transData.transform((bbox.x1+10, y))
    ax.text(xd_text, yd, label, transform=ax.transAxes, ha='left', va='center')
    y = bbox.y1
    is_first = False
plt.show()

resulting plot


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接