Como plotar separar DataFrames do Pandas como subtramas?

129

Eu tenho alguns DataFrames do Pandas compartilhando a mesma escala de valor, mas com colunas e índices diferentes. Ao invocar df.plot(), recebo imagens de plotagem separadas. o que eu realmente quero é tê-los todos no mesmo enredo que os sub-enredos, mas infelizmente não estou conseguindo encontrar uma solução para como e gostaria muito de receber alguma ajuda.

Jimmy C
fonte

Respostas:

250

Você pode criar manualmente as subparcelas com matplotlib e, em seguida, plotar os quadros de dados em uma subparcela específica usando a axpalavra - chave. Por exemplo, para 4 subparcelas (2x2):

import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=2, ncols=2)

df1.plot(ax=axes[0,0])
df2.plot(ax=axes[0,1])
...

Aqui axesestá uma matriz que contém os diferentes eixos de subparcela, e você pode acessar um apenas indexando axes.
Se você quiser um eixo x compartilhado, poderá fornecer sharex=Truea plt.subplots.

joris
fonte
33
Observe que, irritantemente, .subplots()retorna diferentes sistemas de coordenadas, dependendo das dimensões da matriz de subtramas que você está criando. Portanto, se você retornar subtramas onde, digamos, nrows=2, ncols=1precisará indexar os eixos como axes[0]e axes[1]. Veja stackoverflow.com/a/21967899/1569221
canary_in_the_data_mine
3
@canary_in_the_data_mine Graças, que é realmente irritante ... o seu comentário me salvou algum tempo :) não conseguia descobrir por que eu estava ficandoIndexError: too many indices for array
snd
9
@canary_in_the_data_mine Isso é apenas irritante se argumentos padrão para .subplot()forem usados. Defina squeeze=Falsepara forçar .subplot()a sempre retornar um ndarrayem qualquer caso de linhas e colunas.
Martin Martin
73

Você pode ver, por exemplo, na documentação que demonstra joris answer. Também da documentação, você também pode definir subplots=Truee layout=(,)dentro da plotfunção pandas :

df.plot(subplots=True, layout=(1,2))

Você também pode usar fig.add_subplot()quais parâmetros da grade de subparcela, como 221, 222, 223, 224, etc., conforme descrito na publicação aqui . Bons exemplos de plotagem no quadro de dados do pandas, incluindo sub -plotagens , podem ser vistos neste notebook ipython .

sedeh
fonte
2
embora a resposta de joris seja ótima para o uso geral do matplotlib, ela é excelente para quem deseja usar pandas para visualização rápida de dados. Também se encaixa na pergunta um pouco melhor.
Little Bobby Tables
Lembre-se de que o subplotse layoutkwargs gerarão SOMENTE vários gráficos para um único quadro de dados. Isso está relacionado, mas não é uma solução, para a questão do OP de plotar vários quadros de dados em um único gráfico.
Austin A
1
Esta é a melhor resposta para o uso puro de pandas. Isso não requer a importação direta do matplotlib (embora você deva de qualquer maneira) e não requer loop para formas arbitrárias (pode usar layout=(df.shape[1], 1), por exemplo).
Anatoly Makarevich
20

Você pode usar o estilo familiarizado Matplotlib chamando um figuree subplot, mas você só precisa especificar o eixo atual usando plt.gca(). Um exemplo:

plt.figure(1)
plt.subplot(2,2,1)
df.A.plot() #no need to specify for first axis
plt.subplot(2,2,2)
df.B.plot(ax=plt.gca())
plt.subplot(2,2,3)
df.C.plot(ax=plt.gca())

etc ...

Q-man
fonte
6

Você pode plotar várias subparcelas de vários quadros de dados do pandas usando o matplotlib com um truque simples de fazer uma lista de todos os quadros de dados. Em seguida, use o loop for para plotar subtramas.

Código de trabalho:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# dataframe sample data
df1 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df2 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df3 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df4 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df5 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df6 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
#define number of rows and columns for subplots
nrow=3
ncol=2
# make a list of all dataframes 
df_list = [df1 ,df2, df3, df4, df5, df6]
fig, axes = plt.subplots(nrow, ncol)
# plot counter
count=0
for r in range(nrow):
    for c in range(ncol):
        df_list[count].plot(ax=axes[r,c])
        count=+1

insira a descrição da imagem aqui

Usando esse código, você pode plotar subtramas em qualquer configuração. Você precisa apenas definir o número de linhas nrowe o número de colunas ncol. Além disso, você precisa fazer uma lista dos quadros de dados df_listque deseja plotar.

Dr. Arslan
fonte
2
preste atenção ao erro de digitação na última linha: não é count =+1mascount +=1
PEBKAC
4

Você pode usar isto:

fig = plt.figure()
ax = fig.add_subplot(221)
plt.plot(x,y)

ax = fig.add_subplot(222)
plt.plot(x,z)
...

plt.show()
Joe
fonte
3

Você pode não precisar usar o Pandas. Aqui está um gráfico matplotlib de frequências de gatos:

insira a descrição da imagem aqui

x = np.linspace(0, 2*np.pi, 400)
y = np.sin(x**2)

f, axes = plt.subplots(2, 1)
for c, i in enumerate(axes):
  axes[c].plot(x, y)
  axes[c].set_title('cats')
plt.tight_layout()
duhaime
fonte
1

Com base na resposta @joris acima, se você já estabeleceu uma referência para a subparcela, também pode usá-la. Por exemplo,

ax1 = plt.subplot2grid((50,100), (0, 0), colspan=20, rowspan=10)
...

df.plot.barh(ax=ax1, stacked=True)
DaveL17
fonte
0

Como criar vários gráficos a partir de um dicionário de quadros de dados com dados longos (organizados)

  • Premissas

    • Existe um dicionário de vários quadros de dados de dados organizados
      • Criado lendo os arquivos
      • Criado separando um único quadro de dados em vários quadros de dados
    • As categorias cat,, podem estar sobrepostas, mas todos os quadros de dados podem não conter todos os valores decat
    • hue='cat'
  • Como os quadros de dados estão sendo iterados, não há garantia de que as cores sejam mapeadas da mesma forma para cada plotagem

    • Um mapa de cores personalizado precisa ser criado a partir dos 'cat'valores exclusivos para todos os quadros de dados
    • Como as cores serão as mesmas, coloque uma legenda ao lado das plotagens, em vez de uma legenda em cada plot

Importações e dados sintéticos

import pandas as pd
import numpy as np  # used for random data
import random  # used for random data
import matplotlib.pyplot as plt
from matplotlib.patches import Patch  # for custom legend
import seaborn as sns
import math import ceil  # determine correct number of subplot


# synthetic data
df_dict = dict()
for i in range(1, 7):
    np.random.seed(i)
    random.seed(i)
    data_length = 100
    data = {'cat': [random.choice(['A', 'B', 'C']) for _ in range(data_length)],
            'x': np.random.rand(data_length),
            'y': np.random.rand(data_length)}
    df_dict[i] = pd.DataFrame(data)


# display(df_dict[1].head())

  cat         x         y
0   A  0.417022  0.326645
1   C  0.720324  0.527058
2   A  0.000114  0.885942
3   B  0.302333  0.357270
4   A  0.146756  0.908535

Crie mapeamentos de cores e plotagem

# create color mapping based on all unique values of cat
unique_cat = {cat for v in df_dict.values() for cat in v.cat.unique()}  # get unique cats
colors = sns.color_palette('husl', n_colors=len(unique_cat))  # get a number of colors
cmap = dict(zip(unique_cat, colors))  # zip values to colors

# iterate through dictionary and plot
col_nums = 3  # how many plots per row
row_nums = math.ceil(len(df_dict) / col_nums)  # how many rows of plots
plt.figure(figsize=(10, 5))  # change the figure size as needed
for i, (k, v) in enumerate(df_dict.items(), 1):
    plt.subplot(row_nums, col_nums, i)  # create subplots
    p = sns.scatterplot(data=v, x='x', y='y', hue='cat', palette=cmap)
    p.legend_.remove()  # remove the individual plot legends
    plt.title(f'DataFrame: {k}')

plt.tight_layout()
# create legend from cmap
patches = [Patch(color=v, label=k) for k, v in cmap.items()]
# place legend outside of plot; change the right bbox value to move the legend up or down
plt.legend(handles=patches, bbox_to_anchor=(1.06, 1.2), loc='center left', borderaxespad=0)
plt.show()

insira a descrição da imagem aqui

Trenton McKinney
fonte