0

How do we set number of x-ticks for a relplot in Python? Our graphs looks like the following:

enter image description here

Our present graph has included 7 dates in months, but we would like all months included as x-ticks. We would like to set the number of x-ticks to 12, with the following as x-axis labels:

months = ['2020-01', '2020-02', '2020-03', '2020-04', '2020-05', '2020-06', '2020-07', '2020-08', '2020-09', '2020-10', '2020-11', '2020-12']

Following is the function that generates the graph:

def create_lineplot(dataframe):

    months = mdates.MonthLocator()  # every month
    years_fmt = mdates.DateFormatter('%Y-%m')  # This is a format. Will be clear in Screenshot

    # Filtering data to only select relevant columns and data from the year 2020
    dataframe = dataframe[['dev_id', 'outside_temperature', 'datetime']]
    dataframe["datetime"] = pd.to_datetime(dataframe["datetime"])
    dataframe_2020 = dataframe[dataframe['datetime'].dt.year == 2020]

    fig, axes = plt.subplots(figsize=(20, 2))

    mdf = pd.melt(dataframe_2020, id_vars=['datetime', 'dev_id'], var_name=['Temperature'])

    g = sns.relplot(data=mdf, x='datetime', y='value', kind='line', hue='Temperature', height=5, aspect=3)
    g._legend.remove()

    axes.xaxis.set_major_locator(months)
    axes.xaxis.set_major_formatter(years_fmt)
    axes.xaxis.set_minor_locator(months)

    plt.xticks(rotation='vertical')
    plt.tight_layout()
    plt.legend(loc='upper left')

    plt.savefig('lineplot.png')

    plt.show()

An example of our data:

enter image description here

Buster3650
  • 470
  • 2
  • 8
  • 19
  • 1
    **[Don't Post Data Screenshots](https://meta.stackoverflow.com/questions/303812/)**. This question needs a [SSCCE](http://sscce.org/). Always provide a [mre], with **code, data, errors, current output, and expected output, as [formatted text](https://stackoverflow.com/help/formatting)**. It's likely the question will be down-voted and closed. You're discouraging assistance, as no one wants to retype data/code, and screenshots are often illegible. [edit] the question and **add text**. Plots are okay. See [How to provide a reproducible dataframe](https://stackoverflow.com/questions/52413246). – Trenton McKinney Dec 06 '21 at 18:42
  • @JohanC i am using matplotlib version 3.3.2 and pandas version 1.1.4 – Buster3650 Dec 06 '21 at 20:24
  • After following your last instruction it actually worked!! Thank you very much for your time and effort. As the answer is a comment i cant tick it as the correct answer – Buster3650 Dec 06 '21 at 20:27

1 Answers1

2

The main problem of the code is that a dummy fig and axes are created while a figure-level function is used. As such, sns.relplot creates its own figure and axes. You can use axes = g.axes.flat[0] to grab its first ax. When using a figure-level function, you should remove the call to fig, axes = plt.subplots(...).

Alternatively, you could call the related axes-level function and pass the ax: sns.lineplot(..., ax=axes).

import matplotlib.pyplot as plt
from matplotlib import dates as mdates
import seaborn as sns
import pandas as pd
import numpy as np

dataframe = pd.DataFrame({'datetime': pd.date_range('20200101', periods=366, freq='D'),
                          'val1': np.random.normal(0.01, .2, 366).cumsum() + 20,
                          'val2': np.random.normal(0.03, .25, 366).cumsum() + 25})

months_locator = mdates.MonthLocator()  # every month
years_fmt = mdates.DateFormatter('%Y-%m')  # This is a format. Will be clear in Screenshot

dataframe["datetime"] = pd.to_datetime(dataframe["datetime"])
dataframe_2020 = dataframe[dataframe['datetime'].dt.year == 2020]

mdf = dataframe_2020.melt(id_vars=['datetime'], value_vars=['val1', 'val2'])

g = sns.relplot(data=mdf, x='datetime', y='value', hue='variable', kind='line', height=5, aspect=3)
g._legend.remove()
axes = g.axes.flat[0]

axes.xaxis.set_major_locator(months_locator)
axes.xaxis.set_major_formatter(years_fmt)

axes.legend(loc='upper left')
axes.tick_params(axis='x', rotation=90)
axes.margins(x=0)

plt.tight_layout()
plt.show()

sns.relplot with changed axes formatter

JohanC
  • 71,591
  • 8
  • 33
  • 66