5.4 圖表繪制 : 作圖模板的擴(kuò)展 : 添加副軸及細(xì)分類

# -*- coding:utf-8 -*-
import numpy as np
import pandas as pd
from IPython.display import Image as ShowImage
import matplotlib.pyplot as plt
import matplotlib as mpl
import matplotlib.font_manager as mfm
import matplotlib.gridspec as gridspec
import matplotlib.ticker as plticker

目標(biāo)圖表形式

ShowImage('./source/twinx.png')
data = pd.read_csv('./source/data_4.csv', index_col=0)
data.head()

繼承模板

觀察多線圖和上一章中柱形圖的差異,可以發(fā)現(xiàn)以下結(jié)構(gòu)有不同:

  • 畫圖方式:由折線圖和柱狀圖組成
  • Tick顯示:顯示日期
  • Legend在上側(cè)
  • y軸的Major tick label左右側(cè)都有瘤礁,而且還有y軸Label

所以在這些部分我們需要進(jìn)行相關(guān)的自定義

首先我們定義雙軸的通用Image類

%run Images.py
class ImageTwinx(Image):
    def __init__(self, title=None, labels=None, data=None, image_path=None, xticks_rotation=40, 
                 legend_name=[], y2=None, title_y=1.2, ylabel_show=True):
        self.ylabel_show = ylabel_show
        self.legend_name = legend_name
        self.marker_style = dict(color=self.default_colors['blue'], linestyle='-')
        # 副軸所用數(shù)據(jù)
        self.y2 = y2
        super(ImageTwinx, self).__init__(title=title, labels=labels, data=data,
        image_path=image_path, xticks_rotation=xticks_rotation, title_y=title_y, legend_name=legend_name)
     
    
    def config_add(self):
        self.set_ylabel()

    # 此處使用Legend作為y軸的Label
    def set_ylabel(self):
        if self.ylabel_show:
            self.ax.set_ylabel(self.legend_name[0], fontproperties=self.ylable_font)
            self.ax2.set_ylabel(self.legend_name[1], fontproperties=self.ylable_font)

    # 添加副軸,要加入init函數(shù)中set_xticks之后,作為初始化的一部分
    def add_ax(self):
        self.ax2 = self.ax.twinx()

    def plot(self):
        self.ax.plot(self.x, self.y, label=self.legend_name[0], **self.marker_style)
        self.ax2.bar(self.x, self.y2, 0.4, zorder=3, label=self.legend_name[1], color=self.default_colors['red'])
        
    def set_spines(self):
        for _ax in [self.ax, self.ax2]:
            _ax.margins(0) # 設(shè)置留白
            _ax.spines['right'].set_visible(False)
            _ax.spines['top'].set_visible(False)
            _ax.spines['left'].set_visible(False)
    def set_tick_marks(self):
        self.ax.tick_params(axis='both', which='both', bottom=False, top=False, 
            labelbottom=True, left=False, right=False, labelleft=True)
        self.ax2.tick_params(axis='both', which='both', bottom=False, top=False, 
            labelbottom=True, left=False, right=False)

    def add_legend(self):
        if not (self.legend_name is None):
            if len(self.legend_name) == 2:
                lines1, labels1 = self.ax.get_legend_handles_labels()
                lines2, labels2 = self.ax2.get_legend_handles_labels()
                self.ax.legend(lines1+lines2, labels1+labels2, loc='upper center', ncol=2, bbox_to_anchor=(0.5, 1.27), prop=self.legend_font, frameon=False)
image = ImageTwinx(data=data[u'平均價格($)'],
                        y2=data[u'平均價格變動量($)'],
                        labels=data[u'日期'],
                        title=u'Top100商品每日平均價格',
                        legend_name=[u'平均價格($)', 
                                     u'平均價格變動量($)'],
                        xticks_rotation=0
                        )

image.init()
image.fig
有雙軸需要設(shè)置副軸grid

此時圖表大部分已經(jīng)符合要求菲驴,但是X軸的ticks需要設(shè)置下顯示方式凄杯,對于labels需要間隔顯示

def set_xticks(self):
    plt.xticks(range(0,self.length,30), 
               self.labels.loc[[0, 30, 60, 90, 120, 150, 180]], 
               fontproperties=self.xticks_font, 
               rotation=self.xticks_rotation
              )

然后我們需要把set_xticks方法加入ImageTwinx中,這里有三種方式可供選擇:

  1. 繼承ImageTwinx類做一個新的子類菠秒,使用set_xticks方法
  2. 用新的set_xticks方法替換掉ImageTwinx類中的set_xticks方法疙剑,相當(dāng)于對類直接改變
  3. 在實(shí)例化之后的ImageTwinx類中bound新的set_xticks方法,需要使用MethodType function in the types module践叠,具體可以參考stackoverflow
class ImageFluctuation(ImageTwinx):
    def set_xticks(self):
        plt.xticks(range(0,self.length,30), self.labels.loc[[0, 30, 60, 90, 120, 150, 180]], fontproperties=self.xticks_font, rotation=self.xticks_rotation)
image = ImageFluctuation(data=data[u'平均價格($)'],
                        y2=data[u'平均價格變動量($)'],
                        labels=data[u'日期'],
                        title=u'Top100商品每日平均價格',
                        legend_name=[u'平均價格($)', 
                                     u'平均價格變動量($)'],
                        xticks_rotation=12 # 設(shè)置x軸ticks的傾斜角度為12度
                        )

image.init()
image.fig
有雙軸需要設(shè)置副軸grid

手動設(shè)置Y軸取值范圍

# image.fig.savefig('./source/twinx.png',  dpi=160, bbox_inches='tight')

作業(yè)

作為作業(yè)言缤,可以自行構(gòu)造一個雙軸Bar形圖

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市禁灼,隨后出現(xiàn)的幾起案子管挟,更是在濱河造成了極大的恐慌,老刑警劉巖弄捕,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件僻孝,死亡現(xiàn)場離奇詭異,居然都是意外死亡守谓,警方通過查閱死者的電腦和手機(jī)穿铆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來分飞,“玉大人悴务,你說我怎么就攤上這事。” “怎么了讯檐?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵羡疗,是天一觀的道長。 經(jīng)常有香客問我别洪,道長叨恨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任挖垛,我火速辦了婚禮痒钝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘痢毒。我一直安慰自己送矩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布哪替。 她就那樣靜靜地躺著栋荸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪凭舶。 梳的紋絲不亂的頭發(fā)上晌块,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機(jī)與錄音帅霜,去河邊找鬼匆背。 笑死,一個胖子當(dāng)著我的面吹牛身冀,可吹牛的內(nèi)容都是我干的钝尸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼搂根,長吁一口氣:“原來是場噩夢啊……” “哼蝶怔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起兄墅,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤踢星,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后隙咸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沐悦,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年五督,在試婚紗的時候發(fā)現(xiàn)自己被綠了藏否。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡充包,死狀恐怖副签,靈堂內(nèi)的尸體忽然破棺而出遥椿,到底是詐尸還是另有隱情,我是刑警寧澤淆储,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布冠场,位于F島的核電站,受9級特大地震影響本砰,放射性物質(zhì)發(fā)生泄漏碴裙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一点额、第九天 我趴在偏房一處隱蔽的房頂上張望舔株。 院中可真熱鬧,春花似錦还棱、人聲如沸载慈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽娃肿。三九已至,卻和暖如春珠十,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凭豪。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工焙蹭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嫂伞。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓孔厉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親帖努。 傳聞我的和親對象是個殘疾皇子撰豺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容