Package: dexplot
DexplotDexplot is a Python library for delivering beautiful data visualizations with a simple and intuitive user experience.GoalsThe primary goals for dexplot are:Maintain a very consistent API with as few functions as necessary to make the desired statistical plotsAllow the user tremendous power without using matplotlibInstallationpip install dexplotBuilt for long and wide dataDexplot is primarily built for long data, which is a form of data where each row represents a single observation and each column represents a distinct quantity. It is often referred to as "tidy" data. Here, we have some long data.Dexplot also has the ability to handle wide data, where multiple columns may contain values that represent the same kind of quantity. The same data above has been aggregated to show the mean for each combination of neighborhood and property type. It is now wide data as each column contains the same quantity (price).UsageDexplot provides a small number of powerful functions that all work similarly. Most plotting functions have the following signature:dxp.plotting_func(x,y,data,aggfunc,split,row,col,orientation,...)x- Column name along the x-axisy- Column name the y-axisdata- Pandas DataFrameaggfunc- String of pandas aggregation function, 'min', 'max', 'mean', etc...split- Column name to split data into distinct groupsrow- Column name to split data into distinct subplots row-wisecol- Column name to split data into distinct subplots column-wiseorientation- Either vertical ('v') or horizontal ('h'). Default for most plots is vertical.Whenaggfuncis provided,xwill be the grouping variable andywill be aggregated when vertical and vice-versa when horizontal. The best way to learn how to use dexplot is with the examples below.Families of plotsThere are two primary families of plots,aggregationanddistribution. Aggregation plots take a sequence of values and return asinglevalue using the function provided toaggfuncto do so. Distribution plots take a sequence of values and depict the shape of the distribution in some manner.AggregationbarlinescattercountDistributionboxviolinhistkdeComparison with SeabornIf you have used the seaborn library, then you should notice a lot of similarities. Much of dexplot was inspired by Seaborn. Below is a list of the extra features in dexplot not found in seabornAbility to graph relative frequency and normalize over any number of variablesNo need for multiple functions to do the same thing (far fewer public functions)Ability to make grids with a single function instead of having to use a higher level function likecatplotPandasgroupbymethods available as stringsAbility to sort by valuesAbility to sort x/y labels lexicographicallyAbility to select most/least frequent groupsx/y labels are wrapped so that they don't overlapFigure size (plus several other options) and available to change without using matplotlibA matplotlib figure object is returnedExamplesMost of the examples below use long data.Aggregating plots - bar, line and scatterWe'll begin by covering the plots thataggregate. An aggregation is defined as a function that summarizes a sequence of numbers with a single value. The examples come from the Airbnb dataset, which contains many property rental listings from the Washington D.C. area.importdexplotasdxpimportpandasaspdairbnb=dxp.load_dataset('airbnb')airbnb.head()neighborhoodproperty_typeaccommodatesbathroomsbedroomspricecleaning_feeratingsuperhostresponse_timelatitudelongitude0ShawTownhouse163.5443325095.0Nowithin an hour38.90982-77.020161Brightwood ParkTownhouse43.541545097.0NoNaN38.95888-77.025542Capitol HillHouse21.51833597.0Yeswithin an hour38.88791-76.996683ShawHouse22.51475098.0NoNaN38.91331-77.024364Kalorama HeightsApartment31.011181591.0Nowithin an hour38.91933-77.04124There are more than 4,000 listings in our dataset. We will use bar charts to aggregate the data.airbnb.shape(4581, 12)Vertical bar chartsIn order to performa an aggregation, you must supply a value foraggfunc. Here, we find the median price per neighborhood. Notice that the column names automatically wrap.dxp.bar(x='neighborhood',y='price',data=airbnb,aggfunc='median')Line and scatter plots can be created with the same command, just substituting the name of the function. They both are not good choices for the visualization since the grouping variable (neighborhood) has no meaningful order.dxp.line(x='neighborhood',y='price',data=airbnb,aggfunc='median')dxp.scatter(x='neighborhood',y='price',data=airbnb,aggfunc='median')Components of the groupby aggregationAnytime theaggfuncparameter is set, you have performed a groupby aggregation, which always consists of three components:Grouping column - unique values of this column form independent groups (neighborhood)Aggregating column - the column that will get summarized with a single value (price)Aggregating function - a function that returns a single value (median)The general format for doing this in pandas is:df.groupby('grouping column').agg({'aggregating column':'aggregating function'})Specifically, the following code is executed within dexplot.airbnb.groupby('neighborhood').agg({'price':'median'})priceneighborhoodBrightwood Park87.0Capitol Hill129.5Columbia Heights95.0Dupont Circle125.0Edgewood100.0Kalorama Heights118.0Shaw133.5Union Station120.0Number and percent of missing values with'countna'and'percna'In addition to all the common aggregating functions, you can use the strings'countna'and'percna'to get the number and percentage of missing values per group.dxp.bar(x='neighborhood',y='response_time',data=airbnb,aggfunc='countna')Sorting the bars by valuesBy default, the bars will be sorted by the grouping column (x-axis here) in alphabetical order. Use thesort_valuesparameter to sort the bars by value.None - sort x/y axis labels alphabetically (default)asc- sort values from least to greatestdesc- sort values from greatest to leastdxp.bar(x='neighborhood',y='price',data=airbnb,aggfunc='median',sort_values='asc')Here, we sort the values from greatest to least.dxp.bar(x='neighborhood',y='price',data=airbnb,aggfunc='median',sort_values='desc')Specify order withx_orderSpecify a specific order of the labels on the x-axis by passing a list of values tox_order. This can also act as a filter to limit the number of bars.dxp.bar(x='neighborhood',y='price',data=airbnb,aggfunc='median',x_order=['Dupont Circle','Edgewood','Union Station'])By default,x_orderand all of the_orderparameters are set to'asc'by default, which will order them alphabetically. Use the string'desc'to sort in the opposite direction.dxp.bar(x='neighborhood',y='price',data=airbnb,aggfunc='median',x_order='desc')Filter for the neighborhoods with most/least frequency of occurrenceYou can usex_orderagain to filter for the x-values that appear the most/least often by setting it to the string'top n'or'bottom n'wherenis an integer. Here, we filter for the top 4 most frequently occurring neighborhoods. This option is useful when there are dozens of unique values in the grouping column.dxp.bar(x='neighborhood',y='price',data=airbnb,aggfunc='median',x_order='top 4')We can verify that the four neighborhoods are the most common.airbnb['neighborhood'].value_counts()Columbia Heights    773
Union Station       713
Capitol Hill        654
Edgewood            610
Dupont Circle       549
Shaw                514
Brightwood Park     406
Kalorama Heights    362
Name: neighborhood, dtype: int64Horizontal barsSetorientationto'h'for horizontal bars. When you do this, you'll need to switchxandysince the grouping column (neighborhood) will be along the y-axis and the aggregating column (price) will be along the x-axis.dxp.bar(x='price',y='neighborhood',data=airbnb,aggfunc='median',orientation='h',sort_values='desc')Switching orientation is possible for most other plots.dxp.line(x='price',y='neighborhood',data=airbnb,aggfunc='median',orientation='h')Split bars into groupsYou can split each bar into further groups by setting thesplitparameter to another column.dxp.bar(x='neighborhood',y='price',data=airbnb,aggfunc='median',split='superhost')We can use thepivot_tablemethod to verify the results in pandas.airbnb.pivot_table(index='superhost',columns='neighborhood',values='price',aggfunc='median')neighborhoodBrightwood ParkCapitol HillColumbia HeightsDupont CircleEdgewoodKalorama HeightsShawUnion StationsuperhostNo85.0129.090.5120.0100.0110.0130.0120.0Yes90.0130.0103.0135.0100.0124.0135.0125.0Set the order of the unique split values withsplit_order, which can also act as a filter.dxp.bar(x='neighborhood',y='price',data=airbnb,aggfunc='median',split='superhost',split_order=['Yes','No'])Like all the_orderparameters,split_orderdefaults to'asc'(alphabetical) order. Set it to'desc'for the opposite.dxp.bar(x='neighborhood',y='price',data=airbnb,aggfunc='median',split='property_type',split_order='desc')Filtering for the most/least frequent split categories is possible.dxp.bar(x='neighborhood',y='price',data=airbnb,aggfunc='median',split='property_type',split_order='bottom 2')Verifying that the least frequent property types are Townhouse and Condominium.airbnb['property_type'].value_counts()Apartment      2403
House           877
Townhouse       824
Condominium     477
Name: property_type, dtype: int64Stacked bar chartsStack all the split groups one on top of the other by settingstackedtoTrue.dxp.bar(x='neighborhood',y='price',data=airbnb,aggfunc='median',split='superhost',split_order=['Yes','No'],stacked=True)Split into multiple plotsIt's possible to split the data further into separate plots by the unique values in a different column with therowandcolparameters. Here, each kind ofproperty_typehas its own plot.dxp.bar(x='neighborhood',y='price',data=airbnb,aggfunc='median',split='superhost',col='property_type')If there isn't room for all of the plots, set thewrapparameter to an integer to set the maximum number of plots per row/col. We also specify thecol_orderto be descending alphabetically.dxp.bar(x='neighborhood',y='price',data=airbnb,aggfunc='median',split='superhost',col='property_type',wrap=2,col_order='desc')Usecol_orderto both filter and set a specific order for the plots.dxp.bar(x='neighborhood',y='price',data=airbnb,aggfunc='median',split='superhost',col='property_type',col_order=['House','Condominium'])Splits can be made simultaneously along row and columns.dxp.bar(x='neighborhood',y='price',data=airbnb,aggfunc='median',split='superhost',col='property_type',col_order=['House','Condominium','Apartment'],row='bedrooms',row_order=[1,2,3])By default, all axis limits are shared. Allow each plot to set its own limits by settingsharexandshareytoFalse.dxp.bar(x='neighborhood',y='price',data=airbnb,aggfunc='median',split='superhost',col='property_type',col_order=['House','Condominium','Apartment'],row='bedrooms',row_order=[1,2,3],sharey=False)Set the width of each bar withsizeThe width (height when horizontal) of the bars is set with thesizeparameter. By default, this value is .9. Think of this number as the relative width of all the bars for a particular x/y value, where 1 is the distance between each x/y value.dxp.bar(x='neighborhood',y='price',data=airbnb,aggfunc='median',split='property_type',split_order=['Apartment','House'],x_order=['Dupont Circle','Capitol Hill','Union Station'],size=.5)Splitting line plotsAll the other aggregating plots work similarly.dxp.line(x='neighborhood',y='price',data=airbnb,aggfunc='median',split='property_type',split_order=['Apartment','House'],x_order=['Dupont Circle','Capitol Hill','Union Station'])Distribution plots - box, violin, histogram, kdeDistribution plots work similarly, but do not have anaggfuncsince they do not aggregate. They take their group of values and draw some kind of shape that gives information on how that variable is distributed.Box plotsBox plots have colored boxes with ends at the first and third quartiles and a line at the median. The whiskers are placed at 1.5 times the difference between the third and first quartiles (Interquartile range (IQR)). Fliers are the points outside this range and plotted individually. By default, both box and violin plots are plotted horizontally.dxp.box(x='price',y='neighborhood',data=airbnb)Split the groups in the same manner as with the aggregation plots.dxp.box(x='price',y='neighborhood',data=airbnb,split='superhost',split_order=['Yes','No'])Order the appearance of the splits alphabetically (in descending order here).dxp.box(x='price',y='neighborhood',data=airbnb,split='property_type',split_order='desc')Filter range of values withx_orderIt's possible to filter the range of possible values by passing in a list of the minimum and maximum tox_order.dxp.box(x='price',y='neighborhood',data=airbnb,split='superhost',x_order=[50,250])Change thexandywhile settingorientationto make vertical bar plots.dxp.box(x='neighborhood',y='price',data=airbnb,orientation='v',split='property_type',split_order='top 2')Violin plots work identically to box plots, but show "violins", kernel density plots duplicated on both sides of a line.dxp.violin(x='price',y='neighborhood',data=airbnb,split='superhost',split_order=['Yes','No'])Splitting by rows and columns is possible as well with distribution plots.dxp.box(x='price',y='neighborhood',data=airbnb,split='superhost',col='property_type',col_order=['House','Condominium','Apartment'],row='bedrooms',row_order=[1,2])HistogramsHistograms work in a slightly different manner. Instead of passing bothxandy, you give it a single numeric column. A vertical histogram with 20 bins of the counts is created by default.dxp.hist(val='price',data=airbnb)We can usesplitjust like we did above and also create horizontal histograms.dxp.hist(val='price',data=airbnb,orientation='h',split='superhost',bins=15)Here, we customize our histogram by plotting the cumulative density as opposed to the raw frequency count using the outline of the bars ('step').dxp.hist(val='price',data=airbnb,split='bedrooms',split_order=[1,2,3],bins=30,density=True,histtype='step',cumulative=True)KDE PlotsKernel density estimates provide an estimate for the probability distribution of a continuous variable. Here, we examine how price is distributed by bedroom.dxp.kde(x='price',data=airbnb,split='bedrooms',split_order=[1,2,3])Graph the cumulative distribution instead on multiple plots.dxp.kde(x='price',data=airbnb,split='bedrooms',split_order=[1,2,3],cumulative=True,col='property_type',wrap=2)Two-dimensional KDE'sProvide two numeric columns toxandyto get a two dimensional KDE.dxp.kde(x='price',y='cleaning_fee',data=airbnb)Create a grid of two-dimensional KDE's.dxp.kde(x='price',y='cleaning_fee',data=airbnb,row='neighborhood',wrap=3)Count plotsThecountfunction graphs the frequency of unique values as bars. By default, it plots the values in descending order.dxp.count(val='neighborhood',data=airbnb)In pandas, this is a straightforward call to thevalue_countsmethod.airbnb['neighborhood'].value_counts()Columbia Heights    773
Union Station       713
Capitol Hill        654
Edgewood            610
Dupont Circle       549
Shaw                514
Brightwood Park     406
Kalorama Heights    362
Name: neighborhood, dtype: int64Relative frequency withnormalizeInstead of the raw counts, get the relative frequency by setting normalize toTrue.dxp.count(val='neighborhood',data=airbnb,normalize=True)Here, we split by property type.dxp.count(val='neighborhood',data=airbnb,split='property_type')In pandas, this is done with thecrosstabfunction.pd.crosstab(index=airbnb['property_type'],columns=airbnb['neighborhood'])neighborhoodBrightwood ParkCapitol HillColumbia HeightsDupont CircleEdgewoodKalorama HeightsShawUnion Stationproperty_typeApartment167299374397244284315323Condominium3570976265425254House131137157471462361175Townhouse73148145431551386161Horizontal stacked count plots.dxp.count(val='neighborhood',data=airbnb,split='property_type',orientation='h',stacked=True,col='superhost')Normalize over different variablesSettingnormalizetoTrue, returns the relative frequency with respect to all of the data. You can normalize over any of the variables provided.dxp.count(val='neighborhood',data=airbnb,split='property_type',normalize='neighborhood',title='Relative Frequency by Neighborhood')Normalize over several variables at once with a list.dxp.count(val='neighborhood',data=airbnb,split='superhost',row='property_type',col='bedrooms',col_order=[1,2],normalize=['neighborhood','property_type','bedrooms'],stacked=True)Wide dataDexplot can also plot wide data, or data where no aggregation happens. Here is a scatter plot of the location of each listing.dxp.scatter(x='longitude',y='latitude',data=airbnb,split='neighborhood',col='bedrooms',col_order=[2,3])If you've already aggregated your data, you can plot it directly without specifyingxory.df=airbnb.pivot_table(index='neighborhood',columns='property_type',values='price',aggfunc='mean')dfproperty_typeApartmentCondominiumHouseTownhouseneighborhoodBrightwood Park96.119760105.000000121.671756133.479452Capitol Hill141.210702104.200000170.153285184.459459Columbia Heights114.676471126.773196135.292994124.358621Dupont Circle146.858942130.709677179.574468139.348837Edgewood108.508197112.846154156.335616147.503226Kalorama Heights122.542254155.92857192.695652158.230769Shaw153.888889158.500000202.114754173.279070Union Station128.458204133.833333162.748571162.167702dxp.bar(data=df,orientation='h')Time seriesstocks=pd.read_csv('../data/stocks10.csv',parse_dates=['date'],index_col='date')stocks.head()MSFTAAPLSLBAMZNTSLAXOMWMTTFBVdate1999-10-2529.842.3217.0282.75NaN21.4538.9916.78NaNNaN1999-10-2629.822.3416.6581.25NaN20.8937.1117.28NaNNaN1999-10-2729.332.3816.5275.94NaN20.8036.9418.27NaNNaN1999-10-2829.012.4316.5971.00NaN21.1938.8519.79NaNNaN1999-10-2929.882.5017.2170.62NaN21.4739.2520.00NaNNaNdxp.line(data=stocks.head(500))