使用下拉和 matplotlib 绘制交互式绘图
Posted
技术标签:
【中文标题】使用下拉和 matplotlib 绘制交互式绘图【英文标题】:Plotting a interactive plot using dropdown and matplotlib 【发布时间】:2021-04-08 05:51:39 【问题描述】:考虑给定的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)
根据给出的信息,我如何创建与滑块和下拉列表相关联的绘图?
【问题讨论】:
【参考方案1】:虽然我无法使用 matplotlib 完成我的任务,但我在寻找答案时遇到了 plotly 和 dash 的教程。这里有一个非常棒的教程:
Plotly Line Graph Tutorial
【讨论】:
【参考方案2】:除了原版的 plotly,checkout plotly 是一个允许更好交互的网络应用程序框架
https://dash.plotly.com/introduction
【讨论】:
以上是关于使用下拉和 matplotlib 绘制交互式绘图的主要内容,如果未能解决你的问题,请参考以下文章
Py之matplotlib:matplotlib库图表绘制中常规设置大全(交互模式清除原有图像设置横坐标显示文字/旋转角度添加图例绘图布局自动调整图像显示图像暂停)