-1

enter image description here

data = {'tenor': ['1w','1m','3m','6m','12m','1y','2y','3y','4y','5y','6y','7y','10y','15y','20y','25y','30y','40y','50y'],'rate_s': [0.02514, 0.026285, 0.0273, 0.0279, 0.029616, 0.026526, 0.026028, 0.024, 0.025958,0.0261375, 0.026355, 0.026, 0.026898, 0.0271745, 0.02741, 0.027, 0.0275, 0.0289,0.0284],'rate_t':[ 0.02314, 0.024285, 0.0253,0.0279, 0.028616, 0.026526,0.027028, 0.024, 0.025958,0.0271375, 0.02355, 0.026, 0.024898, 0.0271745, 0.02641,0.027, 0.0255, 0.0289,0.0284]}

I want to produce the chart in blue with the same format like below. I tried this piece of code but results are not satisfactory (chart in white). It also not showing all x-axis labels. Please suggest.

ax = plt.gca()

df.plot(kind='line',x='tenor',y='rate_s',marker='o',color='green',ax=ax)
df.plot(kind='line',x='tenor',y='rate_y',marker='o', color='red', ax=ax)
ax.minorticks_on()
ax.grid(which='major',linestyle='-', linewidth='0.5', color='blue')
ax.grid(which='minor', linestyle=':', linewidth='0.5', color='black')
plt.show()

tplotlib

Akash
  • 59
  • 7
  • 1
    Can you add what the current code outputs and possible what df is? – gnahum Mar 25 '20 at 18:33
  • please find the fig (white) which i produced. – Akash Mar 25 '20 at 18:37
  • In regards to the ticks, you can have a custom ticks (as shown here: https://stackoverflow.com/questions/49471424/add-custom-tick-with-matplotlib). For the plot being dark color, you can change it by saying ```plt.style.use('dark-background')``` or see https://matplotlib.org/tutorials/introductory/customizing.html for more info. – gnahum Mar 25 '20 at 18:50
  • can you show me how to create the distance in the gridlines. The gridlines should be based on the distance as shown in blue graph. – Akash Mar 25 '20 at 19:08
  • Can you elaborate on what you mean for the distance in the grid lines and how they are dependent on the blue graph? – gnahum Mar 25 '20 at 19:16
  • In my df, tenor data point starts from 1w till 40y with equal gridline distance. In the blue graph vertical gridlines are shown in distance from 10y to 20y ...spaces are wide. In my graph that difference is not visible. I hope am clear now. – Akash Mar 25 '20 at 19:33
  • You can try to do log scale, or define your own distance line as shown here: https://matplotlib.org/3.1.0/gallery/scales/scales.html If you want I can come up with a quick example – gnahum Mar 25 '20 at 21:21
  • @gnahum..I really need an example.in line with my problem mentioned above. Please suggest with example. – Akash Mar 26 '20 at 15:18
  • I provided an example in the solutions. – gnahum Mar 26 '20 at 18:53
  • Is this question not practically identical to [this previous one of yours](https://stackoverflow.com/questions/60852602/matplotlib-how-to-produce-the-below-chart-containing-all-x-axis-labels-and-gri)? – AMC Mar 26 '20 at 20:44
  • Does this answer your question? [Matplotlib : How to produce the below chart containing all x-axis labels and gridlines accordingly?](https://stackoverflow.com/questions/60852602/matplotlib-how-to-produce-the-below-chart-containing-all-x-axis-labels-and-gri) – AMC Mar 26 '20 at 20:45

1 Answers1

0

This is following the discussions in the comments.

There are a couple parts, the full example is at the bottom.

Style

One of your questions was how to change the style of the plot. This can be done with the following code:

import matplotlib.pyplot as plt 
plt.style.use('seaborn-darkgrid')

there are many possible styles, and you can even create your own style if you wish. To see all possible styles see: the documentation. To list all styles use plt.style.available

Custom Ticker

For the custom tickers: you can use FixedLocator or if you know it is log or symlog, then matplotlib has a built-in locator. See the matplotlib doc for scales

You can use FixedLocator to set up the axis, to be separated. i.e. the following code will give you what you want.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

X = np.arange(0, 2000)
Y = np.arange(0, 2000)

def convert(date): 
    if 'w' in date: 
        return 7*int(date[:-1])
    if 'm' in date: 
        return 30*int(date[:-1]) 
    if 'y' in date: 
        return 30*int(date[:-1]) + 360   
ticks = [convertdate(d) for d in tenor]
plt.style.use('seaborn-darkgrid') 
ax = plt.axes()
t = ticker.FixedLocator(locs=ticks)
ax.xaxis.set_ticklabels(tenor)
ax.xaxis.set_major_locator(t)
# ax.xaxis.set_minor_locator(ticker.MultipleLocator(3))

plt.plot(X, Y, c = 'k')
plt.show()

Which produces: enter image description here

Specific Case

For your specific case, you probably want the custom tickers to be on a specific interval (i.e. smallest of rate_t, biggest of rate_t).

Thus you would need to change the convert function to be as following:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

x = data['rate_t']
y = data['rate_s']

def get_indices(date): 
    if 'w' in date: 
        return 7*int(date[:-1])
    if 'm' in date: 
        return 30*int(date[:-1]) 
    if 'y' in date: 
        return 30*int(date[:-1]) + 360   

def convert(indices): 
    x = np.linspace(min(data['rate_t']), max(data['rate_t']), indices[-1] + 1)
    return x[indices]
indices = [get_indices(d) for d in tenor]
ticks = convert(indices)
plt.style.use('seaborn-darkgrid') 
ax = plt.axes()
t = ticker.FixedLocator(locs=ticks)
ax.xaxis.set_ticklabels(tenor)
ax.xaxis.set_major_locator(t)
# ax.xaxis.set_minor_locator(ticker.MultipleLocator(3))

plt.plot(x, y, c = 'k')
plt.show()

(assuming the data['rate_s'] and data['rate_t'] are as is and without processing)

Which would produce this: enter image description here

Let me know if you have any questions.

gnahum
  • 426
  • 1
  • 5
  • 13