How to make the calendar start-date equal to the start-date in my CSV file?

I have a calendar in my web app and I want it to only allow users to select the dates on the calendar that are actually present in my CSV file or df. Because only those dates have assigned to them a ‘sensor’ observation.

The code it regards are these two pieces:

# Initialize data frame

df1 = pd.read_csv(
     "/Users/ME/Desktop/personal_project/plot_points.csv",
    dtype=object,
)
df = pd.concat([df1], axis=0)
df["Date/Time"] = pd.to_datetime(df["Date/Time"], format="%Y-%m-%d %H:%M")
df.index = df["Date/Time"]
df.drop("Date/Time", 1, inplace=True)
totalList = []
for month in df.groupby(df.index.month):
    dailyList = []
    for day in month[1].groupby(month[1].index.day):
        dailyList.append(day[1])
    totalList.append(dailyList)
totalList = np.array(totalList)

and this piece:

html.H2("Date Plotting"),
                        html.Div(
                            className="div-for-dropdown",
                            children=[
                                dcc.DatePickerSingle(
                                    id="date-picker",
                                    min_date_allowed=dt(2019, 1, 1),
                                    max_date_allowed=dt(2019, 12, 31),
                                    # initial_visible_month=dt(2019, 3, 1),
                                    date=dt(2019, 3, 1).date(),
                                    display_format="MMMM DD, YYYY",
                                    style={"border": "0px solid white"}
                                )
                            ],
                        ),

Probably I need to specify something at this line:

min_date_allowed=dt(2019, 1, 1)

Can someone help me out as to what needs to be done to realise my
goal?


My entire code:

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import numpy as np

from dash.dependencies import Input, Output
from plotly import graph_objs as go
from plotly.graph_objs import *
from datetime import datetime as dt

app = dash.Dash(
    __name__, meta_tags=[{"name": "viewport", "content": "width=device-width"}]
)
server = app.server


# Plotly mapbox public token
mapbox_access_token = get_token [this is intentionally put on private for this post]

# Initialize data frame
df1 = pd.read_csv(
     "/Users/ME/Desktop/personal_project/plot_points.csv",
    dtype=object,
)
df = pd.concat([df1], axis=0)
df["Date/Time"] = pd.to_datetime(df["Date/Time"], format="%Y-%m-%d %H:%M")
df.index = df["Date/Time"]
df.drop("Date/Time", 1, inplace=True)
totalList = []
for month in df.groupby(df.index.month):
    dailyList = []
    for day in month[1].groupby(month[1].index.day):
        dailyList.append(day[1])
    totalList.append(dailyList)
totalList = np.array(totalList)

# Layout of Dash App HTML
app.layout = html.Div(
    children=[
        html.Div(
            className="row",
            children=[
                # Column for user controls
                html.Div(
                    className="four columns div-user-controls",
                    children=[
                        html.Img(
                            className="logo", src=app.get_asset_url("dash-logo-new-.png")
                        ),
                        html.H2("Date Plotting"),
                        html.Div(
                            className="div-for-dropdown",
                            children=[
                                dcc.DatePickerSingle(
                                    id="date-picker",
                                    min_date_allowed=dt(2019, 1, 1),
                                    max_date_allowed=dt(2019, 12, 31),
                                    # initial_visible_month=dt(2019, 3, 1),
                                    date=dt(2019, 3, 1).date(),
                                    display_format="MMMM DD, YYYY",
                                    style={"border": "0px solid white"}
                                )
                            ],
                        ),
                        # Change to side-by-side for mobile layout
                        html.Div(
                            className="row",
                            children=[
                                html.Div(
                                    className="div-for-dropdown",
                                    children=[
                                        # Dropdown for locations on map
                                        dcc.Dropdown(
                                            id="location-dropdown",
                                            options=[
                                                {"label": i, "value": i}
                                                for i in list_of_fixed_sensors
                                            ],
                                            placeholder="Select a sensor viewpoint",
                                        )
                                    ],
                                ),
                                html.Div(
                                    className="div-for-dropdown",
                                    children=[
                                        # Dropdown to select times
                                        dcc.Dropdown(
                                            id="bar-selector",
                                            options=[
                                                {
                                                    "label": str(n) + ":00",
                                                    "value": str(n),
                                                }
                                                for n in range(24)
                                            ],
                                            multi=True,
                                            placeholder="Select certain hours",
                                        )
                                    ],
                                ),
                            ],
                        ),
                        html.H1(id="total-observations"),
                        html.H1(id="total-observations-selection"),
                        html.H1(id="date-value"),
                        html.Button('Detect', id='button'),
                        html.Div(id='output-container-button',
                        children='Hit the button to update.')
                     ],
                ),
                # Column for app graphs and plots
                html.Div(
                    className="eight columns div-for-charts bg-grey",
                    children=[
                        dcc.Graph(id="map-graph"),
                        html.Div(
                            className="text-padding",
                            children=[
                                "Select any of the bars on the histogram to section data by time."
                            ],
                        ),
                        dcc.Graph(id="histogram"),
                    ],
                ),
            ],
        )
    ]
)

SOLUTION

I made the following alterations to the date and day to solve two issues that were causing some issue to prevent calendar-start-date correlation with actual date/time in CSV file:

  • List-out-of-Range issue.
  • The fact that totalList[month][…] outputs wrong data as there was a mismatch between totalList and the date/time of the actual CSV.

I have advanced (refactored) on the following code-snippets to obtain the solution significant to the graph, the histogram and the string that outputs total observations. Basically, the date and day have been corrected. One can compare these new snippet advancements with my original code in the post above.

With these advancements the calendar shows empty results for the
list-items that don’t contain observations and shows the actual
correlating results of those list-items that do possess the
observations.

First advancement: added csv to consider the day/times of year.

df2 = pd.read_csv(
    "2019daytimes.csv",
    dtype=object,
)

df = df.append(df2, ignore_index=True, sort=True)

Second advancement: made the calendar start from first day of observations (static approach not dynamic (I know, later date= should be dynamic and dependent on the first date/time of observations captured in any assigned CSV))

dcc.DatePickerSingle(
                     id="date-picker",
                     min_date_allowed=dt(2019, 1, 1),
                     max_date_allowed=dt(2019, 12, 31),
                     date=dt(2019, 3, 23).date(),
                     display_format="MMMM DD, YYYY",
                     style={"border": "0px solid white"})

Third advancement: added totalList[date_picked.month-1][date_picked.day-1]) - 24

# Update the total number of observations
@app.callback(Output("total-observations", "children"), [Input("date-picker", "date")])
def update_total_rides(datePicked):
    date_picked = dt.strptime(datePicked, "%Y-%m-%d")
    return "Total number of observations: {:,d}".format(
        len(totalList[date_picked.month-1][date_picked.day-1]) - 24
    )

Fourth advancement: added [date_picked.month-1][date_picked.day-1] and -1 at end of totalInSelection += len() and if(totalInSelection < 0): totalInSelection = 0

def update_total_rides_selection(datePicked, selection):
    firstOutput = ""

    if selection is not None or len(selection) is not 0:
        date_picked = dt.strptime(datePicked, "%Y-%m-%d")
        totalInSelection = 0
        for x in selection:
            totalInSelection += len(
                totalList[date_picked.month-1][date_picked.day-1][
                    totalList[date_picked.month-1][date_picked.day-1].index.hour
                    == int(x)
                    ]
            )-1
        if(totalInSelection < 0):
            totalInSelection  = 0
        firstOutput = "Total observations for selected time: {:,d}".format(totalInSelection)

Fifth advancement: added -1 for month and day of date_picked. And yVal -1

def update_histogram(datePicked, selection):
    date_picked = dt.strptime(datePicked, "%Y-%m-%d")
    # print(update_histogram)
    monthPicked = date_picked.month-1
    dayPicked = date_picked.day-1

    [xVal, yVal, colorVal] = get_selection(monthPicked, dayPicked, selection)
    #print(xVal)
    #print(yVal)
    yVal = yVal - 1

Sixed advancement: added -1 at month and day of date_picked.

def update_graph(datePicked, selectedData, selectedLocation):
    zoom = 10.5
    latInitial = -10.8736
    lonInitial = 20.1067
    bearing = 0

    if selectedLocation:
        zoom = 13.0
        latInitial = list_of_fixed_sensors[selectedLocation]["lat"]
        lonInitial = list_of_fixed_sensors[selectedLocation]["lon"]

    date_picked = dt.strptime(datePicked, "%Y-%m-%d")
    monthPicked = date_picked.month-1
    dayPicked = date_picked.day-1
    listCoords = getLatLonColor(selectedData, monthPicked, dayPicked)