matplotlib 如何为散点图添加标题和自定义标签的图例,并以用户想要的任何方式放置图例?

0g0grzrc  于 2023-06-23  发布在  其他
关注(0)|答案(2)|浏览(142)

我已经创建了一个散点图,其中某个列ABC的值从0到10不等。
点有四种颜色:小于2的值为浅蓝色,2-4为蓝色,4-6为橙子,6及以上为棕色。
我已经成功地生成了散点图,但是我发现很难提到图上的图例。
我想要一个图例的标题,图例应该在1行中,而不是在多行中,我还想添加标签到图例中。
变量colour_names有我想添加到图例中的标签。
下面是创建散点图的代码。

x = np.array(df['Date'])
y = np.array(df['PR'])
colours = np.array(df['colour'])
colormap = np.array(['cyan', 'dodgerblue', 'orangered','brown'])
colour_names = ['very less', 'less', 'good', 'more']

scatter = plt.scatter(x,y, c = colormap[colours], s = 5)`

我尝试了以下方法来添加图例,但它既没有给出错误,也没有输出。散点图打印正确,但没有图例

`plt.legend(handles=scatter.legend_elements()[0], 
           labels=colour_names,
           title="ABC")`

我也试过

handles = scatter.legend_elements()[0]
ax.legend(title='ABC', handles=handles, labels=colour_names)

偶尔在我的试错中,我会收到以下消息:-

UserWarning: Collection without array used. Make sure to specify the values to be colormapped via the c argument.

和/或

WARNING:matplotlib.legend:No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
e4yzc0pl

e4yzc0pl1#

您可以根据您的条件对数据进行切片并绘制单独的散点图。假设你的值和颜色是固定的,这将工作。希望这就是你要找的...

## My dataframe with data and PR
df=pd.DataFrame({'PR':np.random.uniform(low=0, high=4, size=(100,)),
                'Date':pd.date_range('2019/07/01', periods=100, freq='SM')})

## One scatter plot each for PR value in range.. data is filtered for the range
plt.scatter(data=df[df.PR > 3], x='Date', y='PR', c = 'cyan' , s = 5, label='more')
plt.scatter(data=df[(df.PR <= 3) & (df.PR > 2)], x='Date', y='PR', c = 'dodgerblue' , s = 5, label='good')
plt.scatter(data=df[(df.PR <= 2) & (df.PR > 1)], x='Date', y='PR', c = 'orangered' , s = 5, label='less')
plt.scatter(data=df[df.PR < 1], x='Date', y='PR', c = 'brown' , s = 5, label='very less')

plt.legend(title='ABC', ncol=4)
plt.show()

nfg76nw0

nfg76nw02#

没有Pandas

import matplotlib.pyplot as plt
import numpy as np

# generate fake data
np.random.seed(20230615)
low, high, N  = 0, 10, 60
x = np.random.randint(low, high+1, N)
y = np.random.rand(N)*(high-low)+low

# compute the intervals
fences = [2, 4, 6]
intervals = [tup for tup in zip([low]+fences, fences+[high+1])]

# colors and labels
colors = 'cyan dodgerblue orangered brown'.split()
labels = 'smallest small good large'.split()

# draw the ranges
for y0 in fences:
    plt.axhline(y0, color='gray', ls='--', lw=0.7)
    
# plot the different ranges
for (low, hi), c, l in zip(intervals, colors, labels):
    idx = np.logical_and(y>=low, y<hi)
    plt.scatter(x[idx], y[idx], label=l, color=c, ec='k', s=120)

# fix the y limits to make space for the legend    
ymn, ymx = plt.ylim()
plt.ylim(ymax=ymx+(ymx-ymn)*0.15)
plt.yticks(range(0, high+1, 2 ))

# let's finish
plt.legend(title='ABC', ncol=4)
plt.show()

相关问题