Pyplot / Matplotlib: How to achieve a compressed y-axis

人走茶凉 提交于 2020-01-03 03:37:28

问题


I am using pyplot to create a climograph based on the visualization of Walter/Lieth.

Climograph Walter/Lieth

Another Climograph by Walter/Lieth

As you can see on the images (the links above), the right y-axis is compressed starting from the value of 100. Their visual distance gets smaller while their numerical intervals become larger.

I can't figure out how to achieve this in pyplot. I know how to set the tick values to create a custom scale but of course they always are equidistant. As you can see in my plot the plotted space on the right y-axis corresponds to the interval of the values:

Maybe someone could give a hint on how to achieve the effect shown in the two links above.

Cheers!


回答1:


An example for you:

import matplotlib.pyplot as plt
axes = plt.axes()
axes.set_xlim([-10, 10]) #whatever, optional
axes.set_ylim([0, 1.0]) # whatever, optional
axes.set_xticks([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5])
axes.set_yticks([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,150,200,300])
plt.plot(x, norm.pdf(x)) #random filler
plt.plot(x, norm.pdf(x, 70.0, 0.1)) #another absolutely random filler
plt.show()

My example only shows how you can tweak the Y coordinate ticks, as you wanted to know. Sorry for not being too helpful apparently. I do not understand the downvote at all. There will probably be better answers, I guess.

For actual compression of the samples (data) there are a few ways:

  • Use a function to scale the data. Maybe defined in steps. i.e. for 0 < n < 10 leave it as it is, for 10 <= n <100 turn into 11~19, etc.

  • Use log scales ( https://matplotlib.org/examples/pylab_examples/log_demo.html )




回答2:


Answer by OP, edited out of their question:

Solution Here is an example for a solution based on Attersons answer. The scaling function was taken from this answer.

from matplotlib import pyplot as plt

def scale(val, src, dst):
        """
        Scale the given value from the scale of src to the scale of dst.
        """
        return ((val - src[0]) / (src[1]-src[0])) * (dst[1]-dst[0]) + dst[0]

# Actual data
data = [20, 50, 100, 250, 600, 200, 150, 100, 40, 30, 25, 20]

source_scale = (100, 600) # Scale values between 100 and 600
destination_scale = (100, 150) # to a scale between 100 and 150

# Apply scale to all items of data that are above or equal to 100
data_scaled = [x if x < 100 else scale(x, source_scale, destination_scale) for x in data]

# Set up a simple plot
fig = plt.figure()
ax = plt.Axes(fig, [0.,0.,1.,1.])
fig.add_axes(ax)

# Set the y-ticks to a custom scale
ax.set_yticks([0,20,40,60,80,100,110,120,130,140,150])
ax.set_ylim(0, 150)
# Set the labels to the actual values
ax.set_yticklabels(["0","20","40","60","80","100","200","300","400","500","600"])

ax.plot(data_scaled)



来源:https://stackoverflow.com/questions/50282054/pyplot-matplotlib-how-to-achieve-a-compressed-y-axis

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!