My sample data start with values beginning with 700 so that there is nothing between 0 and 700. I want to cut that range out of the line plot but I also want to point the reader to that cut by visualizing it like this. This example picture is manipulated via a drawing software just to explain what I want.
Something like this is explained in the matplotlib documentation. But I do not understand what happens there in the example code. And I am not sure if it fits to my case because the example cutting data. And I just want to cut the area where is no data present.
Here is a minimal working example producing line figure where the y-axis starts at 700 not 0. Can we start from here?
#!/usr/bin/env python3
import random as rd
import matplotlib.pyplot as plt
import pandas as pd
# version info
print(pd.__version__) # 1.2.5
print(matplotlib.__version__) # 3.5.1
print(plt.get_backend()) # TkAgg
# sample data
rd.seed(0)
data = [rd.sample(range(700, 850), 12) for i in range(3)]
df = pd.DataFrame(data)
# not sure if this is a usual maptlotlib/pyplot approach to
# simply plot three lines
fig, (ax) = plt.subplots(1, 1)
for row in range(3):
ax.plot(df.iloc[row])
# limit range of y-axis to the data only
ax.set_ylim(bottom=650,
top=900)
plt.show()
That is the result.
By the way: I am also often confused by all the matplotlib based approaches how to draw figures; there are submodules (pyplot, ...) and pandas itself have an API (pandas.DataFrame.plot()
). It is hard bringing this together and to decide where to start.
The matplotlib example you provided the link for shows how to plot data at different parts of the scale using two different subplots. You can use the same technique in your case and modify the height ratio of the bottom subplot to get the result you want.
See code below:
import random as rd
import matplotlib.pyplot as plt
import pandas as pd
# sample data
rd.seed(0)
data = [rd.sample(range(700, 850), 12) for i in range(3)]
df = pd.DataFrame(data)
fig, (ax1, ax2) = plt.subplots(2, 1,
sharex=True,
gridspec_kw={
'height_ratios': [1, 0.1]
})
fig.subplots_adjust(hspace=0.05)
for row in range(3):
ax1.plot(df.iloc[row])
ax2.plot(df.iloc[row])
ax1.set_ylim(700, 900) # outliers only
ax2.set_ylim(0, 100) # most of the data
# limit range of y-axis to the data only
# remove x-axis line's between the two sub-plots
ax1.spines['bottom'].set_visible(False) # 1st subplot bottom x-axis
ax2.spines['top'].set_visible(False) # 2nd subplot top x-axis
# 1st x-axis: move ticks from bottom to top
ax1.xaxis.tick_top()
ax1.tick_params(labeltop=False) # no labels
# 2nd x-axis: ticks on the bottom
ax2.xaxis.tick_bottom()
# 1st subplot y-axis: remove first tick
ax1.set_yticks(ax1.get_yticks()[1:])
# 2nd subplot y-axis: remove the last
ax2.set_yticks(ax2.get_yticks()[:-1])
# now draw the cut
d = .5 # proportion of vertical to horizontal extent of the slanted line
kwargs = dict(
marker=[(-1, -d), (1, d)],
markersize=12, # "length" of cut-line
linestyle='none',
color='k', # ?
mec='k', # ?
mew=1, # line thickness
clip_on=False
)
ax1.plot([0, 1], [0, 0], transform=ax1.transAxes, **kwargs)
ax2.plot([0, 1], [1, 1], transform=ax2.transAxes, **kwargs)
plt.show()
And the output gives:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With