Pandas Matplotlib三轴组合图表循环

gab6jxml  于 2023-08-01  发布在  其他
关注(0)|答案(2)|浏览(91)

我有一个pandas dataframe(df0),从中得到唯一代码并放入df1。然后,我需要创建图表,从df1循环列表检索数据df0。这是一个较大数据集的虚拟版本,将根据某些标准进行过滤。
我需要为代码列中的每个项目创建三重y轴组合图,如下所示代码A和B:

的数据



到目前为止,我已经能够使用循环从透视表创建条形图:

import numpy as np
import pandas as pd
from numpy.random import randn
import matplotlib.pyplot as plt
import caffeinate

np.random.seed(100)
df0 = pd.DataFrame([])
df0['Date'] = ['2020-01-01','2020-01-02','2020-01-03','2020-01-04','2020-01-05','2020-01-06','2020-01-07','2020-01-08','2020-01-09','2020-01-10',
              '2020-01-01','2020-01-02','2020-01-03','2020-01-04','2020-01-05','2020-01-06','2020-01-07','2020-01-08','2020-01-09','2020-01-10']
df0['Code'] = ['A','A','A','A','A','A','A','A','A','A','B','B','B','B','B','B','B','B','B','B']
df0['WindSpeed'] = np.random.randint(1,150,size = (20,1))
df0['Precipitation'] = np.random.randint(1,20,size = (20,1))
df0['Temperature'] = np.random.randint(1,50,size = (20,1))

df1 = pd.DataFrame([])
df1 = df0['Code'].unique()
df1.flatten()
#for item in df1:
#    print(df0['Code'])

for item in df1:
    #pd.pivot_table(data=df0, index='Date', columns='Code', values='Close').plot.bar()
    pd.pivot_table(df0[df0.Code==item], index = 'Date',columns = None).plot.bar(title = item)
plt.show()

字符串
理想情况下,我想使用这种方法,但我还不能从它创建三重Y轴图表。
最接近的是下面的,但产生了两个相同的图表:

df0 = pd.DataFrame([])
df0['Date'] = ['2020-01-01','2020-01-02','2020-01-03','2020-01-04','2020-01-05','2020-01-06','2020-01-07','2020-01-08','2020-01-09','2020-01-10',
              '2020-01-01','2020-01-02','2020-01-03','2020-01-04','2020-01-05','2020-01-06','2020-01-07','2020-01-08','2020-01-09','2020-01-10']
df0['Code'] = ['A','A','A','A','A','A','A','A','A','A','B','B','B','B','B','B','B','B','B','B']
df0['Windspeed'] = np.random.randint(1,150,size = (20,1))
df0['Precipitation'] = np.random.randint(1,20,size = (20,1))
df0['Temperature'] = np.random.randint(1,50,size = (20,1))

df1 = pd.DataFrame([])
df1 = df0['Code'].unique()
df1.flatten()

####MATPLOTLIB 3 AXIS - BARS:
def chartFunc(item):
    data = df0[df0.Code==item]
    index = df0.Date
    x = index
    # Create figure and axis #1
    fig, ax1 = plt.subplots()
    # plot line chart on axis #1
    p1, = ax1.plot(x, df0['Windspeed'])
    #invalid syntax:
    #p1, = ax1.plot(x, df0[(df0.Code ==item) & (df0['Close'])
    ax1.set_ylabel('Windspeed')
    ax1.set_ylim(df0['Windspeed'].min(), df0['Windspeed'].max())
    #ax1.legend(['Open'], loc="upper left")
    ax1.legend(['Windspeed'], loc="upper left")
    ax1.yaxis.label.set_color(p1.get_color())
    ax1.yaxis.label.set_fontsize(14)
    ax1.tick_params(axis='y', colors=p1.get_color(), labelsize=14)
    
    
    # set up the 2nd axis
    ax2 = ax1.twinx() 
    # plot bar chart on axis #2
    p2 = ax2.bar(x, df0['Precipitation'], color='orange')
    
    #ax2.grid(False) # turn off grid #2
    ax2.set_ylabel('Precipitation')
    ax2.set_ylim(df0['Precipitation'].min(), df0['Precipitation'].max())
    
    ax2.legend(['Precipitation'], loc="upper center")
    #ax2.yaxis.label.set_color()
    ax2.yaxis.label.set_fontsize(14)
    #ax2.tick_params(axis='y', colors=p2.get_color(), labelsize=14)

    # set up the 3rd axis
    ax3 = ax1.twinx()
    # Offset the right spine of ax3.    
    ax3.spines.right.set_position(("axes", 1.25))
    # Plot line chart on axis #3
    p3, = ax3.plot(x, df0['Temperature'], color='red')
    ax3.grid(False) # turn off grid #3
    ax3.set_ylabel('Temperature')
    ax3.set_ylim(df0['Temperature'].min(), df0['Temperature'].max())
    ax3.legend(['Temperature'], loc="upper right")
    ax3.yaxis.label.set_color(p3.get_color())
    ax3.yaxis.label.set_fontsize(14)
    ax3.tick_params(axis='y', colors=p3.get_color(), labelsize=14)
    

for item in df1:
    chartFunc(item)
    plt.show()


输出是相同的两张图表。


的字符串
任何帮助都是真诚的感谢。

kdfy810k

kdfy810k1#

问题是你在函数内部通过item进行过滤...

data = df0[df0.Code==item]

字符串
但是,在每种情况下绘制df0

p1, = ax1.plot(x, df0['Windspeed'])
p2 = ax2.bar(x, df0['Precipitation'], color='orange')
p3, = ax3.plot(x, df0['Temperature'], color='red')

您需要将这些更改为data,如下所示。
首先,将index = df0.Date更改为index = df0[df0.Code==item].Date
然后,按照下面的方式改变每个图

p1, = ax1.plot(x, data['Windspeed'])
p2 = ax2.bar(x, data['Precipitation'], color='orange')
p3, = ax3.plot(x, data['Temperature'], color='red')

这将给予你不同的情节你正在寻找...


的数据


cfh9epnr

cfh9epnr2#

也许你可以用一个子图表来计算降水量,像这样:

def chartFunc(df):
    params = {'hspace': 0.1, 'height_ratios': [3, 1]}
    fig, (ax1, ax3) = plt.subplots(2, 1, figsize=(9, 7), sharex=True, gridspec_kw=params)
    ax2 = ax1.twinx()
    x = df.index
    
    # Windspeed
    c = '#1f77b4'
    ax1.plot(x, df['Windspeed'], color=c)
    ax1.set_ylabel('Windspeed')
    ax1.set_ylim(df['Windspeed'].min(), df['Windspeed'].max())
    ax1.legend(['Windspeed'], loc='upper left')
    ax1.yaxis.label.set_color(c)
    ax1.yaxis.label.set_fontsize(14)
    ax1.tick_params(axis='y', colors=c, labelsize=14)
    
    # Precipitation
    c = '#ff7f0e'
    p3 = ax3.bar(x, df['Precipitation'], color=c)
    ax3.set_ylabel('Precipitation')
    ax3.set_ylim(df['Precipitation'].min(), df['Precipitation'].max())
    ax3.legend(['Precipitation'], loc='upper left')
    ax3.yaxis.label.set_color(c)
    ax3.yaxis.label.set_fontsize(14)
    ax3.tick_params(axis='y', colors=c, labelsize=14)
    
    # Temperature
    c = '#d62728'
    ax2.plot(x, df['Temperature'], color='red')
    ax2.set_ylabel('Temperature')
    ax2.set_ylim(df['Temperature'].min(), df['Temperature'].max())
    ax2.legend(['Temperature'], loc='upper right')
    ax2.yaxis.label.set_color(c)
    ax2.yaxis.label.set_fontsize(14)
    ax2.tick_params(axis='y', colors=c, labelsize=14)

    plt.suptitle('Historic data')
    ax3.tick_params(axis='x', labelrotation=45)

df0['Date'] = pd.to_datetime(df0['Date'])
df1 = df0.set_index(['Date', 'Code']).unstack().swaplevel(axis=1).sort_index(axis=1)
for code, df in df1.groupby('Code', axis=1):
    chartFunc(df[code])
    plt.show()

字符串
输出量:


的数据


相关问题