英文:
How to add legend for a scatter plot with title and customized labels and position the legend in any way user wants?
问题
I've translated the relevant part of your text:
我已经创建了一个散点图,其中我有一个特定列 ABC 的值范围从 0 到 10。
这些点有4种颜色:小于2的值为浅蓝色,2-4的为蓝色,4-6的为橙色,6及以上为棕色。
我已成功生成了散点图,但我发现很难在图上添加图例。
我希望图例有一个标题,图例应该在一行中而不是多行中,我还想在图例上添加标签。
变量 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.
希望这有助于解决您的问题。
英文:
I have created a scatter chart where I have values of a certain column ABC ranging from 0-10.
The points have 4 colours: light blue for values less than 2, blue for 2-4, orange for 4-6 and brown for 6 and above.
I have successfully generated the scatter chart, however I am finding it difficult to mention the legend on the plot.
I want a title of the legend and the legend should be in 1 row and not in multiple rows, I also want to add labels to the legend.
The variable colour_names
has the labels that I want to add to the legend.
Following is the code to create the scatter chart.
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)`
I've tried the following ways to add the legend, but it neither gives an error, nor an output. The scatter gets printed properly but without the legend
`plt.legend(handles=scatter.legend_elements()[0],
labels=colour_names,
title="ABC")`
I also tried
handles = scatter.legend_elements()[0]
ax.legend(title='ABC', handles=handles, labels=colour_names)
Occasionally in my trial and error i get the following messages:-
UserWarning: Collection without array used. Make sure to specify the values to be colormapped via the c argument.
and
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.
答案1
得分: 0
你可以根据你的条件对数据进行切片,并绘制单独的散点图。这将在你的数值和颜色固定的情况下工作。希望这是你所寻找的内容...
英文:
You can slice the data based on your condition and plot separate scatter plots. This will work assuming your values and colors are fixed. Hope this is what you are looking for...
## 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()
答案2
得分: 0
[![输入图像描述][1]][1]
没有Pandas
```python
import matplotlib.pyplot as plt
import numpy as np
# 生成虚假数据
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
# 计算区间
fences = [2, 4, 6]
intervals = [tup for tup in zip([low]+fences, fences+[high+1])]
# 颜色和标签
colors = 'cyan dodgerblue orangered brown'.split()
labels = '最小 小 好 大'.split()
# 绘制范围
for y0 in fences:
plt.axhline(y0, color='gray', ls='--', lw=0.7)
# 绘制不同范围
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)
# 调整y轴限制以腾出空间给图例
ymn, ymx = plt.ylim()
plt.ylim(ymax=ymx+(ymx-ymn)*0.15)
plt.yticks(range(0, high+1, 2 ))
# 完成
plt.legend(title='ABC', ncol=4)
plt.show()
<details>
<summary>英文:</summary>
[![enter image description here][1]][1]
No 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()
[1]: https://i.stack.imgur.com/bOKAg.png
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论