使用RGB值和坐标绘制Pandas DataFrame的图形

huangapple go评论106阅读模式
英文:

Plotting a Pandas DataFrame with RGB values and coordinates

问题

我有一个包含列 ["x", "y", "r", "g", "b"] 的 pandas DataFrame,其中 x 和 y 表示像素的坐标,r、g、b 表示其 RGB 值。行包含像素网格的每个坐标的条目,并且是唯一的。如何使用 matplotlib 的 imshow() 函数显示这个 DataFrame?这需要将数据重塑为形状为 (M, N, 3) 的数组。

我通常使用 plt.imshow(df.pivot(columns="x", index="y", values="i"), interpolation="nearest") 的方法只适用于灰度图像。将 ["r", "g", "b"] 作为值参数会产生一个带有多级索引的 DataFrame。然而,我无法将其转换为正确的图像。简单地调用 .reshape(M, N, 3) 会创建一个错误的图像。

我还想过使用 df["rgb"] = list(zip(df.r, df.g, df.b)) 创建一个新列。然而,我不确定如何将结果元组转换为 ndarray 的新轴。

英文:

I have a pandas DataFrame with the columns ["x", "y", "r", "g", "b"] where x and y denote the coordinates of a pixel and r, g, b denote its RGB value. The rows contain entries for each coordinate of a grid of pixels and are unique. How can I display this DataFrame using matplotlibs's imshow()? This requires reshaping the data into a array of shape (M, N, 3).

My usual approach of using plt.imshow(df.pivot(columns="x", index="y", values="i"), interpolation="nearest") does only work for greyscale images. Placing ["r", "g", "b"] as the values argument yields a DataFrame with a MultiIndex as columns. However I fail to convert this into a correct image. Simply calling .reshape(M, N, 3) creates a wrong image.

I also had the idea of creating a new column with df["rgb"] = list(zip(df.r, df.g, df.b)) However I'm not sure on how to convert the resulting tuples into a new axis for the ndarray.

答案1

得分: 5

有一种简单的方法可以做到这一点。首先,你需要确保DataFrame按照x和y值进行排序,可以使用df = df.sort_values(by=['x', 'y'])

接下来,你可以通过调用df[['r', 'g', 'b']]来选择DataFrame中的r、g和b三列。然后,通过调用df[['r', 'g', 'b']].values将这些值转换为一个numpy数组,该数组的形状为(M*N, 3),其中M和N分别是图像的宽度和高度。

现在,将该数组重新调整为形状为(M, N, 3)的数组,就完成了操作。

df = df.sort_values(by=['x', 'y'])
values = df[['r', 'g', 'b']].values
image = values.reshape(df['x'].max() + 1, df['y'].max() + 1, 3)

这里假设DataFrame中的x和y值从0开始,因此在计算图像的维度时需要加1。如果x和y值从1开始,可以这样调整数组的形状:(df['x'].max(), df['y'].max(), 3)

根据你认为图像的x和y维度是什么,你可能需要在最后对数组进行转置。

英文:

There exists an easy way to do this. First, you make sure the DataFrame is sorted by x- and y-values using df = df.sort_values(by=['x', 'y']).

Next, you select only the three columns for r, g and b from the DataFrame by calling df[['r', 'g', 'b']]. You convert the values into a numpy array by calling df[['r', 'g', 'b']].values, which will return an array of the shape (M*N, 3), assuming that M and N are the width and height of your image.
Now, reshape that array into the shape (M, N, 3) and you are done.

df = df.sort_values(by=['x', 'y'])
values = df[['r', 'g', 'b']].values
image = values.reshape(df['x'].max() + 1 , df['y'].max() + 1, 3)

I'm assuming here that your x and y values in the DataFrame start at 0, therefore I add 1 for the dimensions. If your x and y values start at 1, the reshaping can be done like this (df['x'].max(), df['y'].max(), 3).

Depending on what you consider the x and y dimensions of your image, you might have to transpose the array in the end.

答案2

得分: 3

假设有以下示例数据:

   x  y    r    g    b
0  1  0    0  255  255
1  5  1  255  255    0
2  4  2  255    0  255
3  4  0    0  255  255
4  3  1  255  255    0
5  2  3  255    0    0

你可以使用以下代码:

N = df['x'].max()+1
M = df['y'].max()+1

tmp = (df.pivot(columns='x', index='y', values=['r', 'g', 'b'])
         .reindex(index=range(M),
                  columns=pd.MultiIndex.from_product([['r', 'g', 'b'],
                                                      range(N)
                                                     ]))
         .sort_index(level=1, axis=1, sort_remaining=False)
         .to_numpy().reshape((M, N, 3))
      )

plt.imshow(tmp, interpolation='nearest')

输出结果如下图所示:

使用RGB值和坐标绘制Pandas DataFrame的图形

另外,如果你已经有了所有的 x 和 y 值:

np.random.seed(0)
M, N = 4, 5
df = pd.DataFrame({'x': np.repeat(np.arange(N), M),
                   'y': np.tile(np.arange(M), N),
                   'r': np.random.randint(0, 256, M*N),
                   'g': np.random.randint(0, 256, M*N),
                   'b': np.random.randint(0, 256, M*N),
                  })

tmp = (df[['x', 'y', 'r', 'g', 'b']]
 .melt(['x', 'y'], var_name='color')
 .assign(color=lambda d: pd.Categorical(d['color'],
                                        categories=['r', 'g', 'b'],
                                        ordered=True))
 .sort_values(by=['y', 'x', 'color'])
 ['value'].to_numpy()
 .reshape(M, N, 3)
)

plt.imshow(tmp, interpolation='nearest')

输出结果如下图所示:

使用RGB值和坐标绘制Pandas DataFrame的图形

英文:

Assuming this example:

   x  y    r    g    b
0  1  0    0  255  255
1  5  1  255  255    0
2  4  2  255    0  255
3  4  0    0  255  255
4  3  1  255  255    0
5  2  3  255    0    0

You could use:

N = df['x'].max()+1
M = df['y'].max()+1

tmp = (df.pivot(columns='x', index='y', values=['r', 'g', 'b'])
         .reindex(index=range(M),
                  columns=pd.MultiIndex.from_product([['r', 'g', 'b'],
                                                      range(N)
                                                     ]))
         .sort_index(level=1, axis=1, sort_remaining=False)
         .to_numpy().reshape((M, N, 3))
      )

plt.imshow(tmp, interpolation='nearest')

Output:

使用RGB值和坐标绘制Pandas DataFrame的图形

Alternatively, if you have all x/y:

np.random.seed(0)
M, N = 4, 5
df = pd.DataFrame({'x': np.repeat(np.arange(N), M),
                   'y': np.tile(np.arange(M), N),
                   'r': np.random.randint(0, 256, M*N),
                   'g': np.random.randint(0, 256, M*N),
                   'b': np.random.randint(0, 256, M*N),
                  })

tmp = (df[['x', 'y', 'r', 'g', 'b']]
 .melt(['x', 'y'], var_name='color')
 .assign(color=lambda d: pd.Categorical(d['color'],
                                        categories=['r', 'g', 'b'],
                                        ordered=True))
 .sort_values(by=['y', 'x', 'color'])
 ['value'].to_numpy()
 .reshape(M, N, 3)
)

plt.imshow(tmp, interpolation='nearest')

Output:

使用RGB值和坐标绘制Pandas DataFrame的图形

huangapple
  • 本文由 发表于 2023年8月8日 22:03:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76860320.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定