简体   繁体   中英

Matplotlib apply xaxis and yaxis number formatting

  1. Why is my xaxis not formatted as a date? I expect it to because I am setting the dataframe index to a datetime index.
  2. How do I make all subplots share the same xaxis? The reason I am currently using add_subplot instead of plt.subplots is because I couldn't get plt.subplots to work for what I want to do -- which is to make nrows and ncols dynamic parameters so I can output charts with any shape I want: (4,1) shape, (2,2), (1,4), etc.
  3. How do I apply a specific number format to each yaxis? Below, I am attempting to lookup the plot string in d (dict) to return the format string and then apply that format to the yaxis formatting but it doesn't seem to be working.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
plt.style.use('ggplot')

df = pd.DataFrame({'Clicks': {0: 334, 1: 554, 2: 433, 3: 5353, 4: 433},
                   'Impressions': {0: 3242, 1: 43345, 2: 3456, 3: 34543, 4: 3453},
                   'Day': {0: '12/1/2015', 1: '12/2/2015', 2: '12/3/2015', 3: '12/4/2015', 4: '12/5/2015'},
                   'Conv': {0: 23, 1: 23, 2: 45, 3: 56, 4: 45},
                   'Cost': {0: 414.16, 1: 686.96, 2: 536.91, 3: 637.72, 4: 536.91}},
                  columns=['Day', 'Impressions', 'Clicks', 'Cost', 'Conv'])

df['Day'] = pd.to_datetime(df['Day'])
df = df.set_index('Day').resample('d', how='sum')

window = 2
nrows = 2
ncols = 2

plots = ['Impressions', 'Clicks', 'Cost', 'Conv']
d = {'Impressions':'{:,.0f}', 'Clicks': '{:,.0f}', 'Cost':'${:,.2f}', 'Conv': '{:,.0f}'}

fig = plt.figure(figsize=(8,6))
for i, plot in enumerate(plots):
  ax = fig.add_subplot(nrows, ncols, i+1)
  ax.plot(df.index, df[plot])
  ma = pd.rolling_mean(df[plot], window)
  ax.plot(df.index, ma)
  mstd = pd.rolling_std(df[plot], window)
  ax.fill_between(df.index, ma - 2*mstd, ma + 2*mstd, color='b', alpha=0.1)
  ax.set_title(plot)
  ax.get_yaxis().set_major_formatter(FuncFormatter(lambda x, p: d[plot].format(x)))
  plt.tight_layout()

plt.show()

绘图示例

Here's the df :

            Impressions  Clicks    Cost  Conv
Day                                          
2015-12-01         3242     334  414.16    23
2015-12-02        43345     554  686.96    23
2015-12-03         3456     433  536.91    45
2015-12-04        34543    5353  637.72    56
2015-12-05         3453     433  536.91    45

Why is my xaxis not formatted as a date?

You need to set DateFormatter (or similar) as major_formatter - see code below.

How do I make all subplots share the same xaxis?

Add sharex=True parameter to you subplots call. You can use axes from .subplots() if you flatten them like it is shown in the code below.

How do I apply a specific number format to each yaxis?

Your FuncFormatter needs to return a formatted string from given tick_value and position like in the code below:

fig, axes = plt.subplots(2, 2, figsize=(8,6), sharex=True)

for ax, plot in zip(axes.flat, plots):
    ax.plot(df.index, df[plot])
    ma = pd.rolling_mean(df[plot], window)
    ax.plot(df.index, ma)
    mstd = pd.rolling_std(df[plot], window)
    ax.fill_between(df.index, ma - 2*mstd, ma + 2*mstd, color='b', alpha=0.1)
    ax.set_title(plot)
    ax.yaxis.set_major_formatter(FuncFormatter(lambda x, p: '{:.0f}'.format(x)))
    ax.xaxis.set_major_formatter(DateFormatter('%d-%H:%M')) # or '%d.%m.%y'

fig.autofmt_xdate()  # This will rotate the xticklabels by 30 degrees so that all dates are readable.
fig.tight_layout()  # no need to call this inside the loop.

This will produce a plot like this:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM