能用Plot或者Makie画出有两个x轴的图吗


#1

我想用Plot或者Makie画有两个x轴的图,其中一个的值是10000/K (K是开尔文温度),然后另一个轴在相同位置是与之对应的摄氏温度,这种能实现吗

在具体来说就是上面一个轴是这种offset reciprocal scale的,然后再在下面一个值是(10000/K)的轴。


#2

Plot.jl + pyplot()

找了半天,Plot.jl 目前应该还没有画多 X 轴的好办法(没有 twiny());
多 Y 轴可以用 twinx()twinx does not appear when searching the documentation

强行另开了一张图当新的 X 轴:

using Plots
pyplot()

# 产生画图用数据
C = collect(-10:1:45)
degC2K = x -> x + 273.15 # 摄氏度转开尔文
K2degC = x -> x - 273.15
K = degC2K.(C)
y = C.*rand(length(C))

# 计算坐标轴范围,对齐坐标轴
xlims1 = (min(K...), max(K...))
xlims2 = K2degC.(xlims1)

# 1-正常画图
p1 = plot(
    K, y, 
    xlabel = "Kelvin",
    xlims = xlims1, # 建议保留: 用于对齐坐标轴
)

# 2-暴力画坐标轴
# 实际上是另外画了一张图,但只显示 x 轴
p2 = plot(
    # K, zeros(length(K));
    # legend = false,
    # # 以上两句和下面一句二选一,效果一致
    # # 用于自动调整坐标轴范围
    # # 可同时工作
    xlims = xlims2, # 限定坐标轴范围
    axis = :x, # 只显示 x 轴
    xlabel = "deg-C", # x 轴说明文字
    grid = false, # 不显示网格线
)

# 3-纵向排列两张图
plot(
    p1, p2, # 放置两张图
    layout = grid(
        2, 1, # 布局为 两行一列
        heights = [0.99, 0.01] 
        # 这里可以调两个坐标轴的相对大小,相当于调整间距
        # 两个数之和*必须*为 1
        # heights = [0.5, 0.5]      # 超大间距
        # heights = [0.99, 0.01]    # 最小间距
    )
) # ref: [Layouts - Plots](https://docs.juliaplots.org/latest/layouts/#simple-layouts)

效果

看上去我觉得还行,能萌混过关。


#3

感谢老哥写这么多,但是应该不太行。。。
我是想把(10000/K)和摄氏度对应起来,这时候就有了问题。
(10000/K)的值是等间隔,但是摄氏度100到200和200到300的长度都不是相等的,这就真的不知道该怎么办了。


#4

不知道我这次理解的对不对:

实际上是
10000/KCy 作图

尝试了半天确实有点麻烦, plot.jl 操纵坐标轴不是很方便。
下面这版吧 10000/K 画对了。非等距的第二坐标轴没有搞出来。你还是用 origin 画吧。

# Offset Reciprocal plot.jl
using Plots
pyplot()

# 产生画图用数据
C = collect(0:10:100) .+ 1
degC2K = x -> x + 273.15
K2degC = x -> x - 273.15
K = degC2K.(C)
x = 10^4 ./ K
y = C.*rand(length(C))

# 计算坐标轴范围,对齐坐标轴
xlim = (min(x...), max(x...))
Klim = (min(C...), max(C...))

p1 = plot(
    x, y, 
    xlabel = "1/Kelvin",
    xlims = xlim, # 用于对齐坐标轴
    xflip = true,
)
# ref:
# - [flip X-axis - Plots](https://docs.juliaplots.org/latest/examples/pyplot/#global)

# 2-暴力画坐标轴
p2 = plot(
    xlims = Klim, # 限定坐标轴范围
    axis = :x, # 只显示 x 轴
    # xscale = :log10, # 这句有点问题会报错
    xlabel = "deg-C", # x 轴说明文字
    grid = false, # 不显示网格线
)

# 3-纵向排列两张图
plot(
    p1, p2, # 放置两张图
    layout = grid(
        2, 1, # 布局为 两行一列
        heights = [0.99, 0.01] 
    )
)