簡體   English   中英

如何迭代散點圖的列表列表並創建獨特元素的圖例

[英]How to iterate a list of list for a scatter plot and create a legend of unique elements

背景:

我有一個包含xy值的list_of_x_and_y_list ,如下所示:

[[(44800, 14888), (132000, 12500), (40554, 12900)], [(None, 193788), (101653, 78880), (3866, 160000)]]

我有另一個data_name_list ["data_a","data_b"]以便

  • "data_a" = [(44800, 14888), (132000, 12500), (40554, 12900)]

  • "data_b" = [(None, 193788), (101653, 78880), (3866, 160000)]

list_of_x_and_y_listlen / 或data_name_list len > 20。

題:

如何為data_name_list中的每個項目(顏色相同)創建散點圖?

我嘗試過的:

   fig = plt.figure()
   ax = fig.add_subplot(1, 1, 1)
   ax = plt.axes(facecolor='#FFFFFF')
   prop_cycle = plt.rcParams['axes.prop_cycle']
   colors = prop_cycle.by_key()['color']

   print(list_of_x_and_y_list)
   for x_and_y_list, data_name, color in zip(list_of_x_and_y_list, data_name_list, colors):
       for x_and_y in x_and_y_list,:
          print(x_and_y)
          x, y = x_and_y
          ax.scatter(x, y, label=data_name, color=color) # "label=data_name" creates 
                                                         # a huge list as a legend! 
                                                         # :(


       plt.title('Matplot scatter plot')
       plt.legend(loc=2)
       file_name = "3kstc.png"
       fig.savefig(file_name, dpi=fig.dpi)
       print("Generated: {}".format(file_name))

問題:

傳說似乎是一個很長的清單,我不知道如何糾正:

在此處輸入圖片說明

相關研究:

您得到一個長重復列表作為圖例的原因是因為您將每個點作為一個單獨的系列提供,因為matplotlib不會根據標簽自動對您的數據進行分組。

快速解決方法是迭代列表並將每個系列的 x 值和 y 值壓縮為兩個元組,以便x元組包含所有 x 值, y元組包含 y 值。

然后您可以將這些元組與標簽一起提供給plt.plot方法。

我覺得名字list_of_x_and_y_list是不必要的冗長和復雜,所以在我的代碼中我使用了較短的名字。

import matplotlib.pyplot as plt

data_series = [[(44800, 14888), (132000, 12500), (40554, 12900)],
               [(None, 193788), (101653, 78880), (3866, 160000)]]
data_names = ["data_a","data_b"]

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax = plt.axes(facecolor='#FFFFFF')
prop_cycle = plt.rcParams['axes.prop_cycle']
colors = prop_cycle.by_key()['color']

for data, data_name, color in zip(data_series, data_names, colors):
    x,y = zip(*data)
    ax.scatter(x, y, label=data_name, color=color)
    plt.title('Matplot scatter plot')
    plt.legend(loc=1)

輸出

要讓每個 data_name 只獲取一個條目,您應該只將 data_name 添加一次作為標簽。 其余的調用應該使用label=None 使用當前代碼可以實現的最簡單的方法是在循環結束時將 data_name 設置為None

from matplotlib import pyplot as plt
from random import randint

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.set_facecolor('#FFFFFF')
# create some random data, suppose the sublists have different lengths
list_of_x_and_y_list = [[(randint(1000, 4000), randint(2000, 5000)) for col in range(randint(2, 10))]
                        for row in range(10)]
data_name_list = list('abcdefghij')
colors = plt.rcParams['axes.prop_cycle'].by_key()['color']
for x_and_y_list, data_name, color in zip(list_of_x_and_y_list, data_name_list, colors):
    for x_and_y in x_and_y_list :
        x, y = x_and_y
        ax.scatter(x, y, label=data_name, color=color)
        data_name = None
plt.legend(loc=2)
plt.show()

有些事情可以簡化,使代碼“更pythonic”,例如:

for x_and_y in x_and_y_list :
    x, y = x_and_y

可以寫成:

for x, y in x_and_y_list:

另一個問題是,對於每個點調用scatter的大量數據可能會相當慢。 屬於同一列表的所有 x 和 y 可以繪制在一起。 例如使用列表理解

for x_and_y_list, data_name, color in zip(list_of_x_and_y_list, data_name_list, colors):
    xs = [x for x, y in x_and_y_list]
    ys = [y for x, y in x_and_y_list]
    ax.scatter(xs, ys, label=data_name, color=color)

scatter甚至可以獲得每個點的顏色列表,但是一次性繪制所有點,不允許每個data_name標簽。

很多時候, numpy用於存儲數值數據。 這有一些優點,例如用於快速計算的矢量化。 使用 numpy 代碼如下所示:

import numpy as np

for x_and_y_list, data_name, color in zip(list_of_x_and_y_list, data_name_list, colors):
    xys = np.array(x_and_y_list)
    ax.scatter(xys[:,0], xys[:,1], label=data_name, color=color)

樣地

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM