如何从for循环的绘图结果创建一个图形 [英] How to create one figure from plot results of for loop

查看:48
本文介绍了如何从for循环的绘图结果创建一个图形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个看起来像的数据框

id a1 a2 a3 a4 a5 a6 value1 value21 .2 .3 .4 .2 .1 .2 1 02 .1 .2 .1 .3 .7 .3 1 13 .4 .1 .1 .1 .5 .4 0 04 .5 .3 .3 .4 .6 .1 0 15 .3 .1 .1 .3 .2 .3 0 16 .7 .2 .3 .3 .6 .1 0 07 .2 .6 .8 .1 .2 .4 1 18 .1 .4 .2 .1 .9 .3 0 19 .4 .2 .1 .3 .5 .2 1 0cols = ['a1', 'a2', 'a3', 'a4', 'a5', 'a6']标题 = []对于列中的 x:g = sns.lmplot(x = x,y = 'value1',数据 = 数据,scatter_kws={color":black"},line_kws={color":blue"})标题 = x + 'val1'g.set(title = title)标题.附加(标题)plt.show()g = sns.lmplot(x = x,y = 'value2',数据 = 数据,scatter_kws={color":black"},line_kws={color":blue"})标题 = x + 'val2'g.set(title = title)标题.附加(标题)plt.show()

这向我展示了彼此下方的每个数字.我想创建一个图形,该图形在 4 x 2 列中包含所有 8 个图,但列顶部有文本,每个图右侧有文本.像这样:

我试过使用

fig, ((ax1, ax2), (ax3, ax4), (ax5, ax6)) = plt.subplots(3, 2)对于 fig.get_axes() 中的 ax:ax.label_outer()

理想情况下,我正在寻找带有标题和侧面标签的图.但只是有情节的数字会很棒.但我不知道如何将其与我用来生成绘图的代码结合起来.

解决方案

创建

融化的数据框看起来像:

 fig ai val 值0 a1 0.2 值1 11 a1 0.1 值1 12 a1 0.4 值1 03 a1 0.5 值1 04 a1 0.3 值1 0……………………103 a6 0.3 值2 1104 a6 0.1 值2 0105 a6 0.4 value2 1106 a6 0.3 value2 1107 a6 0.2 值2 0

I have a dataframe that looks like

id         a1    a2     a3    a4    a5    a6   value1     value2
 1         .2    .3    .4     .2   .1     .2     1         0
 2         .1    .2    .1     .3   .7     .3     1         1
 3         .4    .1    .1     .1   .5     .4     0         0
 4         .5    .3    .3     .4   .6     .1     0         1
 5         .3    .1    .1     .3   .2     .3     0         1
 6         .7    .2    .3     .3   .6     .1     0         0
 7         .2    .6    .8     .1   .2     .4     1         1
 8         .1    .4    .2     .1   .9     .3     0         1
 9         .4    .2    .1     .3   .5     .2     1         0
 
cols = ['a1', 'a2', 'a3', 'a4', 'a5', 'a6']
titles = []

for x in cols:
    
    g = sns.lmplot(x = x,
           y = 'value1', 
           data = data,
           scatter_kws={"color": "black"}, line_kws={"color": "blue"})

    title = x + 'val1'
    g.set(title = title)
    titles.append(title)
    plt.show()


    g = sns.lmplot(x = x,
                   y = 'value2', 
                   data = data,
                   scatter_kws={"color": "black"}, line_kws={"color": "blue"})
    title = x + 'val2'
    g.set(title = title)
    titles.append(title)
    plt.show()

This shows me each figure under each other. I want to create a figure that has all 8 plots in a 4 by 2 column but there is text on top of the columns and text to the right of each plot. Like so:

I have tried using

fig, ((ax1, ax2), (ax3, ax4), (ax5, ax6)) = plt.subplots(3, 2)

for ax in fig.get_axes():
    ax.label_outer()

Ideally, I am looking for the plots with the title and side labvels. But just the figure with plots would be great. But I don't know how to incorporate this with the code I am using to generate the plots.

解决方案

To create an lmplot for the complete dataframe, the data needs to be in long form. As there are two sets of columns, pd.melt() needs to be called twice, taking care the columns of melted dataframe get different names. These names will then be used for the col and row of the created FacetGrid.

The code below chooses fig and ai for the melted columns of a1..a6. And val and value for the melted version of value1 and value2. You 'll probably want to choose different names, consistent with how you want to present your data.

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
from io import StringIO

data_str = '''id         a1    a2     a3    a4    a5    a6   value1     value2
 1         .2    .3    .4     .2   .1     .2     1         0
 2         .1    .2    .1     .3   .7     .3     1         1
 3         .4    .1    .1     .1   .5     .4     0         0
 4         .5    .3    .3     .4   .6     .1     0         1
 5         .3    .1    .1     .3   .2     .3     0         1
 6         .7    .2    .3     .3   .6     .1     0         0
 7         .2    .6    .8     .1   .2     .4     1         1
 8         .1    .4    .2     .1   .9     .3     0         1
 9         .4    .2    .1     .3   .5     .2     1         0'''
df = pd.read_csv(StringIO(data_str), delim_whitespace=True)
df1 = df.melt(value_vars=['a1', 'a2', 'a3', 'a4', 'a5', 'a6'], var_name='fig', value_name='ai',
              id_vars=['value1', 'value2'])
df2 = df1.melt(value_vars=['value1', 'value2'], var_name='val', value_name='value', id_vars=['fig', 'ai'])

g = sns.lmplot(x='ai',
               y='value',
               row='fig',  # 'value1', 'value2'
               col='val',  # 'a1', 'a2', 'a3', 'a4', 'a5', 'a6'
               height=1.3,
               aspect=4,
               data=df2,
               scatter_kws={"color": "black"}, line_kws={"color": "blue"}, )
g.fig.subplots_adjust(left=0.06, bottom=0.06)  # a bit more space for the labels
plt.show()

The melted dataframe looks like:

    fig   ai     val  value
0    a1  0.2  value1      1
1    a1  0.1  value1      1
2    a1  0.4  value1      0
3    a1  0.5  value1      0
4    a1  0.3  value1      0
..   ..  ...     ...    ...
103  a6  0.3  value2      1
104  a6  0.1  value2      0
105  a6  0.4  value2      1
106  a6  0.3  value2      1
107  a6  0.2  value2      0

这篇关于如何从for循环的绘图结果创建一个图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆