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

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

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)的数组,就完成了操作。

  1. df = df.sort_values(by=['x', 'y'])
  2. values = df[['r', 'g', 'b']].values
  3. 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.

  1. df = df.sort_values(by=['x', 'y'])
  2. values = df[['r', 'g', 'b']].values
  3. 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

假设有以下示例数据:

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

你可以使用以下代码:

  1. N = df['x'].max()+1
  2. M = df['y'].max()+1
  3. tmp = (df.pivot(columns='x', index='y', values=['r', 'g', 'b'])
  4. .reindex(index=range(M),
  5. columns=pd.MultiIndex.from_product([['r', 'g', 'b'],
  6. range(N)
  7. ]))
  8. .sort_index(level=1, axis=1, sort_remaining=False)
  9. .to_numpy().reshape((M, N, 3))
  10. )
  11. plt.imshow(tmp, interpolation='nearest')

输出结果如下图所示:

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

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

  1. np.random.seed(0)
  2. M, N = 4, 5
  3. df = pd.DataFrame({'x': np.repeat(np.arange(N), M),
  4. 'y': np.tile(np.arange(M), N),
  5. 'r': np.random.randint(0, 256, M*N),
  6. 'g': np.random.randint(0, 256, M*N),
  7. 'b': np.random.randint(0, 256, M*N),
  8. })
  9. tmp = (df[['x', 'y', 'r', 'g', 'b']]
  10. .melt(['x', 'y'], var_name='color')
  11. .assign(color=lambda d: pd.Categorical(d['color'],
  12. categories=['r', 'g', 'b'],
  13. ordered=True))
  14. .sort_values(by=['y', 'x', 'color'])
  15. ['value'].to_numpy()
  16. .reshape(M, N, 3)
  17. )
  18. plt.imshow(tmp, interpolation='nearest')

输出结果如下图所示:

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

英文:

Assuming this example:

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

You could use:

  1. N = df['x'].max()+1
  2. M = df['y'].max()+1
  3. tmp = (df.pivot(columns='x', index='y', values=['r', 'g', 'b'])
  4. .reindex(index=range(M),
  5. columns=pd.MultiIndex.from_product([['r', 'g', 'b'],
  6. range(N)
  7. ]))
  8. .sort_index(level=1, axis=1, sort_remaining=False)
  9. .to_numpy().reshape((M, N, 3))
  10. )
  11. plt.imshow(tmp, interpolation='nearest')

Output:

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

Alternatively, if you have all x/y:

  1. np.random.seed(0)
  2. M, N = 4, 5
  3. df = pd.DataFrame({'x': np.repeat(np.arange(N), M),
  4. 'y': np.tile(np.arange(M), N),
  5. 'r': np.random.randint(0, 256, M*N),
  6. 'g': np.random.randint(0, 256, M*N),
  7. 'b': np.random.randint(0, 256, M*N),
  8. })
  9. tmp = (df[['x', 'y', 'r', 'g', 'b']]
  10. .melt(['x', 'y'], var_name='color')
  11. .assign(color=lambda d: pd.Categorical(d['color'],
  12. categories=['r', 'g', 'b'],
  13. ordered=True))
  14. .sort_values(by=['y', 'x', 'color'])
  15. ['value'].to_numpy()
  16. .reshape(M, N, 3)
  17. )
  18. 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:

确定