我想以非线性方式缩放 x 轴。也就是说,例如,我想让刻度 1、2、45、100、400 之间相等距离。1 和 2、2 和 45 等之间的比例应该是线性的。我在互联网上搜索了很多次,但找不到线索。
答案1
虽然可能仅使用 LaTeX 就可以完成此操作,但我很懒,所以我使用 Python 和 Numpy 来创建新的 x 值。假设您有一个包含两列数字的数据文件,分别为x
和y
。我在 Python 代码中添加了注释,如果有任何不清楚的地方可以询问。
# I'm using Python 3, but I think this line will make it work with Python 2.x
from __future__ import division
# numpy for number juggling, sys to get arguments from command line
import numpy as np
import sys
# read the two columns from the specified file into x and y
x,y = np.loadtxt(sys.argv[1],unpack=True)
# read tick locations from second argument and convert from str to float
ticks = sys.argv[2]
ticks = [float(i) for i in ticks.split(',')]
# in the case that the data are outside the specified tick locations,
# add a new tick for the smallest and/or largest x-value
if x[0] < ticks[0]:
ticks = [x[0]] + ticks
if x[-1] > ticks[-1]:
ticks = ticks + [x[-1]]
# make a new x-vector including tick locations, and interpolate y-values to tick locs
newx = np.unique((np.concatenate((x,ticks))))
newy = np.interp(newx,x,y)
# set up array for new x-values
weirdx = np.empty_like(newx)
for i in range(len(ticks)-1):
# find all x-values that are between two adjacent ticks
I = np.where( (ticks[i] <= newx) & (newx <= ticks[i+1]) )[0]
if len(I) > 0:
# Algorithm:
# take x values in range and subtract the first value (at first tick), so they start at 0
# divide by the last value (at last tick), so values run from 0 to 1
# add i, where i is the number of the first tick (counting from 0)
subx = newx[I]
subx -= subx[0]
subx /= subx[-1]
subx += i
weirdx[I] = subx
# if the ticks are outside the data range, remove the x and y values at the first/last ticks
if x[-1] < ticks[-1]:
weirdx = np.delete(weirdx, -1)
newy = np.delete(newy,-1)
if x[0] > ticks[0]:
weirdx = np.delete(weirdx, 0)
newy = np.delete(newy,0)
# save new data file, and file with tick labels
np.savetxt('newdata.dat',np.hstack(( weirdx[:,np.newaxis], newy[:,np.newaxis] )), '%.8f')
np.savetxt('ticks.dat', ticks, '%u')
将脚本保存在与数据文件相同的文件夹中并运行
python ticks.py data.dat 1,2,45,200,450
其中ticks.py
是脚本文件的名称,data.dat
是数据文件的名称,1,2,...
是刻度位置列表。请注意,刻度列表中不能有空格。
作为测试,我为直线生成了一些数字y = 2x
,x 介于 0 到 495 之间。输出和 LaTeX 代码如下。请注意,必须手动指定刻度的位置。
\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\pgfplotstableread{newdata.dat}\data
\pgfplotstableread{ticks.dat}\ticky
\begin{document}
\begin{tikzpicture}
\begin{axis}[
xticklabels from table={\ticky}{[index]0},
xtick={0,...,6},
grid]
\addplot [black] table[x index=0,y index=1] {\data};
\end{axis}
\end{tikzpicture}
\end{document}