如何迭代地绘制自定义数据框组

时间:2021-01-23 21:51:53

标签: python pandas matplotlib

我有多个数据框,我从 Excel 工作表中读取了这些数据框,如下所示 -

A = pd.read_excel("sample.xlsx", usecols="A:B", sheet_name="A")
B = pd.read_excel("sample.xlsx", usecols="A:B", sheet_name="B")
...
...

每个数据框都有自己独特的 x 和 y 值,我可以使用以下代码制作组合图 -

ax.plot(A.iloc[:, 0], A.iloc[:, 1], color=colors(0), label='A')
ax.plot(B.iloc[:, 0], B.iloc[:, 1], color=colors(1), label='B')
...
...

我现在想在初始图形中保留这个原始图,但另外还使用相同的数据制作多个图,以便我能够将这些图中的一些组合成一个组并为它们分配一个公共标签。我能想到的一个非常基本和残酷的代码如下 -

ax.plot(A.iloc[:, 0], A.iloc[:, 1], color=colors(0), label='A, B')
ax.plot(B.iloc[:, 0], B.iloc[:, 1], color=colors(0), label='A, B')
...
...

然而,这有一个缺点。如果我这样做,我将有两个标签为 [A, B] 的图例条目。此外,我从多个来源提取了近 50 个这样的数据框,不断更改这些图的所有颜色和标签将是一个繁琐的过程。

有没有办法可以根据需要对这些数据框进行分组并将它们标记为分组实体?我正在想象类似以下的东西 -

ax.plot(A.iloc[:, 0], A.iloc[:, 1], color=colors(0), label='A')
ax.plot(B.iloc[:, 0], B.iloc[:, 1], color=colors(1), label='B')
...
...
set1 = [A, B, C]
set2 = [G, E, F]
ax.legend((set1), ('Legend for Set1'), color=colors(0))
ax.legend((set2), ('Legend for Set2'), color=colors(2))

这些分组也会发生变化,例如,在随后的图中,我想将 (A, C, E) 分组在一起。有没有一种简单的方法可以在 Python 和 Matplotlib 中实现这一点?我是这个社区的新手,所以如果下次我应该以不同的方式提出问题,请告诉我。

Ps - 如果我必须手动将我的组放在单独的标签中,我也很好

ax.legend((A, B, C), ('Legend for Set1'), color=colors(0))

2 个答案:

答案 0 :(得分:1)

  • 使用 pandas.read_excel 中的参数 sheet_name=None 创建 dictdataframes,其中每个工作表名称是一个 keydataframe对于工作表,是 value
    • df_dict = pd.read_excel("sample.xlsx", usecols="A:B", sheet_name=None)
    • 这样可以更轻松地迭代创建每个 dataframe 或自定义 dataframes 组的绘图。

将所有 dataframes 绘制成一个图形

  • 要绘制每个 dataframe,请使用 key 遍历 value df_dict.items() 对。
  • color=colors[i], 可以从 ax.plot(...) 中删除,因为绘图 API 将指定唯一颜色,前提是调色板中的绘图数量不超过唯一颜色。
  • 这演示了如何将所有 dataframes 绘制成一个图形。
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns  # just using it for the color palette
import numpy as np  # for test data

# synthetic dict of dataframes used for plot example
df_dict = dict()
for i in range(1, 4):
    rads = np.arange(0, 2*np.pi, 0.01)
    data = np.sin(i*rads)
    df_dict[f'freq: {i}x'] = pd.DataFrame({'x': rads, 'y': data})

# In your case, create a dict of dataframes by using the parameter sheet_name=None
df_dict = pd.read_excel("sample.xlsx", usecols="A:B", sheet_name=None)

# create colors from a palette; creates a list of colors based on the number of keys in df_dict
colors = sns.color_palette('husl', n_colors=len(df_dict.keys()))

# create a plot figure
fig, ax = plt.subplots(figsize=(8, 6))

# iterate through the dict and enumerate with i, i is used to index the colors
for i, (k, v) in enumerate(df_dict.items()):

    # plot each dataframe, v, and use the key, k, to create a legend label
    ax.plot(v.iloc[:, 0], v.iloc[:, 1], color=colors[i], label=f'{k}')

# place the legend outside the plot figure
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')

enter image description here


绘制自定义组

  • 使用上面的df_dict
  • 必须定义要一起绘制的所有 dataframes 组。
    • 在这种情况下,listtuples 用于定义要一起绘制的组。
# define the groups
groups = [('freq: 1x', 'freq: 2x'), ('freq: 1x', 'freq: 3x')]

# iterate through each group
for i, g in enumerate(groups, 1):
    
    # create a plot figure for the group
    fig, ax = plt.subplots(figsize=(8, 6))
    
    # plot each dataframe in the group
    for key in g:
        
        # get the value for the key
        v = df_dict[key]
        
        # plot each dataframe, v, and use the key to create a legend label
        ax.plot(v.iloc[:, 0], v.iloc[:, 1], label=f'{key}')

    # place the legend outside the plot figure
    plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')

    # set the title
    plt.title(f'Plot of group {i}')

enter image description here

答案 1 :(得分:1)

感谢@Trenton McKinney 提供的解决方案。我正在添加用于最终解决我的问题的最终代码。

tab_size

我使用了上面的代码,因为我希望我的所有图都在同一个图中,但根据组进行标记和着色。

相关问题