matplotlib中是否可以有给定数量n> 2的y轴?

问题描述

prices = pd.DataFrame(np.array([[1,2,3],[4,5,6],[7,8,9]]),columns=['a','b','c'])

我有我的prices数据框,目前有3列。但在其他时候,它可能具有更多或更少的列。有没有一种方法可以使用某种twinx()循环来创建所有(可能)无限数量的y轴的所有不同时间序列的折线图?

我尝试了下面的double for循环,但得到了typeError'd:bTypeError: 'Axessubplot' object does not support item assignment

# for i in range(0,len(prices.columns)):
#     for column in list(prices.columns):
#         fig,ax[i] = plt.subplots()
#         ax[i].set_xlabel(prices.index()) 
#         ax[i].set_ylabel(column[i]) 
#         ax[i].plot(prices.Date,prices[column]) 
#         ax[i].tick_params(axis ='y') 
# 
#         ax[i+1] = ax[i].twinx() 
#         ax[i+1].set_ylabel(column[i+1]) 
#         ax[i+1].plot(prices.Date,column[i+1]) 
#         ax[i+1].tick_params(axis ='y') 
# 
#         fig.suptitle('matplotlib.pyplot.twinx() function \ Example\n\n',fontweight ="bold") 
#         plt.show() 
# =============================================================================

我相信我理解为什么会出错-ax对象不允许分配i变量。我希望有一些巧妙的方法可以完成此任务。

解决方法

结果是,主要问题是您不应将大熊猫绘图功能与matplotlib混合使用,否则会导致轴重复。否则,此matplotlib example的实现会很简单。

from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as AA
from matplotlib import pyplot as plt
from itertools import cycle
import pandas as pd


#fake data creation with different spread for different axes
#this entire block can be deleted if you import your df
from pandas._testing import rands_array
import numpy as np
fakencol=5
fakenrow=7
np.random.seed(20200916)
df = pd.DataFrame(np.random.randint(1,10,fakenrow*fakencol).reshape(fakenrow,fakencol),columns=rands_array(2,fakencol))
df = df.multiply(np.power(np.asarray([10]),np.arange(fakencol)))
df.index = pd.date_range("20200916",periods=fakenrow)

#defining a color scheme with unique colors
#if you want to include more than 20 axes,well,what can I say
sc_color = cycle(plt.cm.tab20.colors)

#defining the size of the figure in relation to the number of dataframe columns
#might need adjustment for optimal data presentation
offset = 60
plt.rcParams['figure.figsize'] = 10+df.shape[1],5

#host figure and first plot
host = host_subplot(111,axes_class=AA.Axes)
h,= host.plot(df.index,df.iloc[:,0],c=next(sc_color),label=df.columns[0])
host.set_ylabel(df.columns[0])
host.axis["left"].label.set_color(h.get_color())
host.set_xlabel("time")

#plotting the rest of the axes
for i,cols in enumerate(df.columns[1:]):
  
    curr_ax = host.twinx()       

    new_fixed_axis = curr_ax.get_grid_helper().new_fixed_axis
    curr_ax.axis["right"] = new_fixed_axis(loc="right",axes=curr_ax,offset=(offset*i,0))
    
    curr_p,= curr_ax.plot(df.index,df[cols],label=cols)
    
    curr_ax.axis["right"].label.set_color(curr_p.get_color())
    curr_ax.set_ylabel(cols)
    curr_ax.yaxis.label.set_color(curr_p.get_color())


plt.legend()
plt.tight_layout()
plt.show()

![enter image description here

想一想-最好将坐标轴均匀地分布在图的左侧和右侧。哦,很好。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...