US Macroeconomic Data Explorer | Zillow Listing and Sales Data

Zillow Listing and Sales Data


A look at residental real estate listing and sales, according to monthly reports from Zillow.

In [1]:
import pandas as pd
import numpy as np
import altair as alt

from datetime import datetime

today = datetime.today()

# 
urls = {
    "Listings_PriceCut": "https://files.zillowstatic.com/research/public_csvs/perc_listings_price_cut/Metro_perc_listings_price_cut_uc_sfrcondo_week.csv",
    "SalesCount": "https://files.zillowstatic.com/research/public_csvs/sales_count_now/Metro_sales_count_now_uc_sfrcondo_month.csv",
    "NewListings": "https://files.zillowstatic.com/research/public_csvs/new_listings/Metro_new_listings_uc_sfrcondo_week.csv",
    "MedianAgeToPending": "https://files.zillowstatic.com/research/public_csvs/med_doz_pending/Metro_med_doz_pending_uc_sfrcondo_week.csv",
    "RentIndex": "https://files.zillowstatic.com/research/public_csvs/zori/Metro_ZORI_AllHomesPlusMultifamily_Smoothed.csv",
}

def doChart(metric='Listings_PriceCut', location='United States', unit='%', zero=True, yoy=False, color='navy', size=3):
    url = urls.get(metric)

    df_raw = pd.read_csv(url, encoding = "ISO-8859-1")

    months = df_raw.columns.to_list()[3:]

    df_tmp = df_raw.set_index('RegionName')[months].T.reset_index()
    print('Most recent data: {}'.format(months[-1]))
    
    if yoy:
        df_yoy = df_tmp[['index', location]].sort_values('index').copy()
        df_yoy = df_yoy.set_index('index')
        df_yoy['Change'] = df_yoy[location].apply(lambda v: v if isinstance(v, float) else np.nan).pct_change(12).apply(lambda v: 100 * v)
        df_yoy = df_yoy.dropna()
        
        #print(df_yoy.tail(20))
        
        return alt.Chart(df_yoy.reset_index()).mark_bar(size=size, color=color).encode(
            alt.X('index:T', axis=alt.Axis(title='', format="%b-%y")),
            alt.Y('Change:Q', axis=alt.Axis(title=metric.replace('_', ' ') + " [{}]".format(unit))),
            color=alt.condition(f"datum['Change'] < 0",
                alt.value('tomato'),
                alt.value(color)
            ),
            tooltip=[alt.Tooltip('Change:Q', format=',.02f'), alt.Tooltip('index:T', format='%B %Y')]
        ).properties(
            title="Zillow {} ({}) YoY Growth over time".format(metric.replace('_', ' '), location),
            width=750,
            height=450,
            background='white'
        )        
    else:
        theFormat = unit if '%' in unit else '$,d' if '$' in unit else ',d'
        return alt.Chart(df_tmp).mark_line(color=color).encode(
            alt.X('index:T', axis=alt.Axis(title='', format="%b-%y")),
            alt.Y('{}:Q'.format(location),
                  scale=alt.Scale(zero=zero),
                  axis=alt.Axis(title=metric.replace('_', ' ') + f" [{unit}]", format=theFormat)),
            tooltip=[alt.Tooltip('{}:Q'.format(location), format=',.02f'),
                     alt.Tooltip('index:T', format='%B %Y')]
        ).properties(
            title="Zillow {} ({}) over time".format(metric.replace('_', ' '), location),
            width=750,
            height=450,
            background='white'
        )
In [2]:
doChart(metric='Listings_PriceCut', location='United States')
Most recent data: 2022-08-06
Out[2]:
In [3]:
c = doChart(metric='SalesCount', location='United States', unit='YoY % Growth', yoy=True, color='teal')
c.save('residential-realestate-zillow.png')
c.display()
Most recent data: 2022-07-31
In [4]:
doChart(metric='SalesCount', location='Chicago, IL', unit='YoY % Growth', yoy=True)
Most recent data: 2022-07-31
Out[4]:
In [5]:
doChart(metric='SalesCount', location='Denver, CO', unit='YoY % Growth', yoy=True)
Most recent data: 2022-07-31
Out[5]:
In [6]:
doChart(metric='SalesCount', location='Des Moines, IA', unit='YoY % Growth', yoy=True)
Most recent data: 2022-07-31
Out[6]:
In [7]:
doChart(metric='Listings_PriceCut', location='Denver, CO')
Most recent data: 2022-08-06
Out[7]:
In [8]:
doChart(metric='NewListings', location='Chicago, IL', unit='# of homes')
Most recent data: 2022-08-06
Out[8]:
In [9]:
doChart(metric='MedianAgeToPending', location='United States', unit='days')
Most recent data: 2022-08-06
Out[9]:
In [10]:
doChart(metric='MedianAgeToPending', location='Dallas-Fort Worth, TX', unit='days')
Most recent data: 2022-08-06
Out[10]:
In [11]:
doChart(metric='MedianAgeToPending', location='Denver, CO', unit='days')
Most recent data: 2022-08-06
Out[11]:
In [12]:
doChart(metric='MedianAgeToPending', location='Phoenix, AZ', unit='days')
Most recent data: 2022-08-06
Out[12]:
In [13]:
doChart(metric='NewListings', location='United States', unit='# of homes')
Most recent data: 2022-08-06
Out[13]:
In [14]:
doChart(metric='SalesCount', location='Denver, CO', unit='# of homes')
Most recent data: 2022-07-31
Out[14]:
In [15]:
doChart(metric='RentIndex', location='United States', unit='$ / month', zero=True)
Most recent data: 2022-07
Out[15]:
In [16]:
doChart(metric='RentIndex', location='Denver, CO', unit='$ / month')
Most recent data: 2022-07
Out[16]:

© kdunn926