使用下拉菜单和 matplotlib 绘制交互式图

Plotting a interactive plot using dropdown and matplotlib

考虑给定的 excel 文件:

我想根据特定符号使用特定日期的 Normalize_Nifty 值绘制交互式线图。为此,我正在使用 ipywidgets。我已经成功创建了一个包含符号列表的下拉列表。这是相同的代码:

widgets.Combobox(
    # value='John',
    placeholder='Choose Symbol',
    options=['APLAPOLLO','AUBANK','AARTIDRUGS','AARTIIND','AAVAS','ABBOTINDIA','ADANIENT','ADANIGAS','ADANIGREEN','ADANIPORTS','ADANITRANS','ABCAPITAL','ABFRL','ADVENZYMES','AEGISCHEM','AFFLE','AJANTPHARM','AKZOINDIA','ALEMBICLTD','APLLTD','ALKEM','ALKYLAMINE','ALOKINDS','AMARAJABAT','AMBER','AMBUJACEM','APOLLOHOSP','APOLLOTYRE','ASHOKLEY','ASHOKA','ASIANPAINT','ASTERDM','ASTRAZEN','ASTRAL','ATUL','AUROPHARMA','AVANTIFEED','DMART','AXISBANK','BASF','BEML','BSE','BAJAJ-AUTO','BAJAJCON','BAJAJELEC','BAJFINANCE','BAJAJFINSV','BAJAJHLDNG','BALKRISIND','BALMLAWRIE','BALRAMCHIN','BANDHANBNK','BANKBARODA','BANKINDIA','MAHABANK','BATAINDIA','BAYERCROP','BERGEPAINT','BDL','BEL','BHARATFORG','BHEL','BPCL','BHARATRAS','BHARTIARTL','INFRATEL','BIOCON','BIRLACORPN','BSOFT','BLISSGVS','BLUEDART','BLUESTARCO','BBTC','BOMDYEING','BOSCHLTD','BRIGADE','BRITANNIA','CARERATING','CCL','CESC','CRISIL','CSBBANK','CADILAHC','CANFINHOME','CANBK','CAPLIPOINT','CGCL','CARBORUNIV','CASTROLIND','CEATLTD','CENTRALBK','CDSL','CENTURYPLY','CENTURYTEX','CERA','CHALET','CHAMBLFERT','CHENNPETRO','CHOLAHLDNG','CHOLAFIN','CIPLA','CUB','COALINDIA','COCHINSHIP','COFORGE','COLPAL','CONCOR','COROMANDEL','CREDITACC','CROMPTON','CUMMINSIND','CYIENT','DBCORP','DCBBANK','DCMSHRIRAM','DLF','DABUR','DALBHARAT','DEEPAKNTR','DELTACORP','DHANI','DHANUKA','DBL','DISHTV','DCAL','DIVISLAB','DIXON','LALPATHLAB','DRREDDY','EIDPARRY','EIHOTEL','EPL','ESABINDIA','EDELWEISS','EICHERMOT','ELGIEQUIP','EMAMILTD','ENDURANCE','ENGINERSIN','EQUITAS','ERIS','ESCORTS','EXIDEIND','FDC','FEDERALBNK','FINEORG','FINCABLES','FINPIPE','FSL','FORTIS','FCONSUMER','FRETAIL','GAIL','GEPIL','GHCL','GMMPFAUDLR','GMRINFRA','GALAXYSURF','GRSE','GARFIBRES','GICRE','GILLETTE','GLAXO','GLENMARK','GODFRYPHLP','GODREJAGRO','GODREJCP','GODREJIND','GODREJPROP','GRANULES','GRAPHITE','GRASIM','GESHIP','GREAVESCOT','GRINDWELL','GUJALKALI','GAEL','FLUOROCHEM','GUJGASLTD','GMDCLTD','GNFC','GPPL','GSFC','GSPL','GULFOILLUB','HEG','HCLTECH','HDFCAMC','HDFCBANK','HDFCLIFE','HFCL','HATHWAY','HATSUN','HAVELLS','HEIDELBERG','HERITGFOOD','HEROMOTOCO','HSCL','HINDALCO','HAL','HINDCOPPER','HINDPETRO','HINDUNILVR','HINDZINC','HONAUT','HUDCO','HDFC','HUHTAMAKI','ICICIBANK','ICICIGI','ICICIPRULI','ISEC','ICRA','IDBI','IDFCFIRSTB','IDFC','IFBIND','IIFL','IIFLWAM','IOLCP','IRB','IRCON','ITC','ITI','INDIACEM','IBULHSGFIN','IBREALEST','INDIAMART','INDIANB','IEX','INDHOTEL','IOC','IOB','IRCTC','INDOCO','IGL','INDUSINDBK','NAUKRI','INFY','INGERRAND','INOXLEISUR','INDIGO','IPCALAB','JBCHEPHARM','JKCEMENT','JKLAKSHMI','JKPAPER','JKTYRE','JMFINANCIL','JSWENERGY','JSWSTEEL','JTEKTINDIA','JAGRAN','JAICORPLTD','J&KBANK','JAMNAAUTO','JINDALSAW','JSLHISAR','JSL','JINDALSTEL','JCHAC','JUBLFOOD','JUSTDIAL','JYOTHYLAB','KEI','KNRCON','KRBL','KSB','KAJARIACER','KALPATPOWR','KANSAINER','KTKBANK','KARURVYSYA','KSCL','KEC','KOLTEPATIL','KOTAKBANK','L&TFH','LTTS','LICHSGFIN','LAOPALA','LAXMIMACH','LTI','LT','LAURUSLABS','LEMONTREE','LINDEINDIA','LUPIN','LUXIND','MASFIN','MMTC','MOIL','MRF','MGL','MAHSCOOTER','MAHSEAMLES','M&MFIN','M&M','MAHINDCIE','MHRIL','MAHLOG','MANAPPURAM','MRPL','MARICO','MARUTI','MFSL','METROPOLIS','MINDTREE','MINDACORP','MINDAIND','MIDHANI','MOTHERSUMI','MOTILALOFS','MPHASIS','MCX','MUTHOOTFIN','NATCOPHARM','NBCC','NCC','NESCO','NHPC','NLCINDIA','NMDC','NOCIL','NTPC','NH','NATIONALUM','NFL','NAVINFLUOR','NAVNETEDUL','NESTLEIND','NETWORK18','NILKAMAL','NAM-INDIA','OBEROIRLTY','ONGC','OIL','OMAXE','OFSS','ORIENTCEM','ORIENTELEC','ORIENTREF','PIIND','PNBHOUSING','PNCINFRA','PSPPROJECT','PTC','PVR','PAGEIND','PERSISTENT','PETRONET','PFIZER','PHILIPCARB','PHOENIXLTD','PIDILITIND','PEL','POLYMED','POLYCAB','POLYPLEX','PFC','POWERGRID','PRAJIND','PRESTIGE','PRSMJOHNSN','PGHL','PGHH','PNB','QUESS','RBLBANK','RECLTD','RITES','RADICO','RVNL','RAIN','RAJESHEXPO','RALLIS','RCF','RATNAMANI','RAYMOND','REDINGTON','RELAXO','RELIANCE','SBICARD','SBILIFE','SJVN','SKFINDIA','SRF','SANOFI','SCHAEFFLER','SCHNEIDER','SIS','SEQUENT','SFL','SHILPAMED','SCI','SHOPERSTOP','SHREECEM','SHRIRAMCIT','SRTRANSFIN','SIEMENS','SOBHA','SOLARINDS','SOLARA','SONATSOFTW','SOUTHBANK','SPICEJET','STARCEMENT','SBIN','SAIL','SWSOLAR','STLTECH','STAR','SUDARSCHEM','SUMICHEM','SPARC','SUNPHARMA','SUNTV','SUNDARMFIN','SUNDRMFAST','SUNTECK','SUPRAJIT','SUPREMEIND','SUPPETRO','SUVENPHAR','SUZLON','SWANENERGY','SWARAJENG','SYMPHONY','SYNGENE','TCIEXP','TCNSBRANDS','TTKPRESTIG','TVTODAY','TV18BRDCST','TVSMOTOR','TASTYBITE','TATACHEM','TATACOFFEE','TATACOMM','TCS','TATACONSUM','TATAELXSI','TATAINVEST','TATAMTRDVR','TATAMOTORS','TATAPOWER','TATASTLBSL','TATASTEEL','TEAMLEASE','TECHM','NIACL','RAMCOCEM','THERMAX','THYROCARE','TIMKEN','TITAN','TORNTPHARM','TORNTPOWER','TRENT','TRIDENT','TIINDIA','UCOBANK','UFLEX','UPL','UJJIVAN','UJJIVANSFB','ULTRACEMCO','UNIONBANK','UBL','MCDOWELL-N','VGUARD','VMART','VIPIND','VRLLOG','VSTIND','VAIBHAVGBL','VAKRANGEE','VTL','VARROC','VBL','VENKEYS','VINATIORGA','IDEA','VOLTAS','WABCOINDIA','WELCORP','WELSPUNIND','WESTLIFE','WHIRLPOOL','WIPRO','WOCKPHARMA','YESBANK','ZEEL','ZENSARTECH','ZYDUSWELL','ECLERX'],
    description='NIFTY50:',
    ensure_option=True,
    disabled=False)

我还创建了包含特定日期范围的滑块,如下面的代码所示:

class DateRangePicker(object):
    def __init__(self,start,end,freq='D',fmt='%Y-%m-%d'):
        """
        Parameters
        ----------
        start : string or datetime-like
            Left bound of the period
        end : string or datetime-like
            Left bound of the period
        freq : string or pandas.DateOffset, default='D'
            Frequency strings can have multiples, e.g. '5H' 
        fmt : string, defauly = '%Y-%m-%d'
            Format to use to display the selected period

        """
        self.date_range=pd.date_range(start=start,end=end,freq=freq)
        options = [(item.strftime(fmt),item) for item in self.date_range]
        self.slider_start = widgets.SelectionSlider(
            description='start',
            options=options,
            continuous_update=False
        )
        self.slider_end = widgets.SelectionSlider(
            description='end',
            options=options,
            continuous_update=False,
            value=options[-1][1]
        )

        self.slider_start.on_trait_change(self.slider_start_changed, 'value')
        self.slider_end.on_trait_change(self.slider_end_changed, 'value')

        self.widget = widgets.Box(children=[self.slider_start,self.slider_end])

    def slider_start_changed(self,key,value):
        self.slider_end.value=max(self.slider_start.value,self.slider_end.value)
        self._observe(start=self.slider_start.value,end=self.slider_end.value)

    def slider_end_changed(self,key,value):
        self.slider_start.value=min(self.slider_start.value,self.slider_end.value)
        self._observe(start=self.slider_start.value,end=self.slider_end.value)

    def display(self):
        display(self.slider_start,self.slider_end)

    def _observe(self,**kwargs):
        if hasattr(self,'observe'):
            self.observe(**kwargs)

def fct(start,end):
    print (start,end)
    
w=DateRangePicker(start='2019-11-22',end="2020-12-22",freq='D',fmt='%Y-%m-%d')
w.observe=fct
w.display()

导入数据帧并对值进行归一化的代码如下所示:

import pandas as pd
import pandas as pd
import numpy as np
from ipywidgets import widgets, interactive
from datetime import datetime

df=pd.read_excel('C:/Users/Administrator/Desktop/Trendig.xlsx')
data=df[['Date','Symbol','Close_Nifty']]
data.head()
Type='Nifty50'
data['Type']=Type
data.head(100000)
data['Normalize_Nifty'] = df.groupby('Symbol')['Close_Nifty'].transform(lambda x: x/x.iloc[0]).fillna(1)#.reset_index()
data.head(10000)

根据给定的信息,我如何创建将其与滑块和下拉菜单相关联的绘图?

虽然我无法使用 matplotlib 完成我的任务,但我在搜索答案时遇到了 plotly 和 dash 的教程。这里有一个这样精彩的教程:

Plotly Line Graph Tutorial

除了 vanilla plotly 之外,checkout plotly dash 是一个允许更好交互的网络应用程序框架

https://dash.plotly.com/introduction