3

Perhaps I've made the title more complicated than the question, but here goes...!

I have some angular data, contiguous in the x-y plane, that straddle the 360 => 0 degree line - ie, 358,359,0,1,2....

If I were plotting these and setting:

 plt.xlim(0,360)

I would of course have three dots at the far left of the plot, and two at the far right. You can see this in the (more complicated, and actual) plot here (x-axis limits deliberately reversed):

the angularly-wrapped dataset

What I'd really like is to have all dots plotted around the same position in the plot window, perhaps towards the centre of the plot. Under this scheme, the x-axis decreases to the left of the 360-0 degree border, and increases to the right.

I don't want to make any translations / shifts to the data itself (it's a large dataset, etc), so I'd be looking to do this with some matplotlib-trickery.

I plan on plotting the datapoints with hexbin, if that makes any difference.

Thanks for looking, and thank you in advance for your help,

Dave

4

1 回答 1

4

老实说,我认为仅转换您的数据会更快。x[x>180] -= 360相当快。除非您的数据集大小为几 GB,否则转换数据所需的时间仅为几毫秒。

因此,这是一种简单的方法(转换数据):

import matplotlib.pyplot as plt
import numpy as np

# Generate data to match yours...
y = 60 * np.random.random(300) - 20
x = 60 * (np.random.random(300) - 0.5)
x[x < 0] += 360

# Transform the data back to a -180 to 180 range...
x[x > 180] -= 360

# Plot the data
fig, ax = plt.subplots()
ax.plot(x, y, 'b.')

# Set the ticks so that negative ticks represent >180 numbers
ticks = ax.get_xticks()
ticks[ticks < 0] += 360
ax.set_xticklabels([int(tick) for tick in ticks])

plt.show()

在此处输入图像描述

然而,如果你想避免转换你的数据,你可以做这样的事情......不过,这 100% 保证比仅仅转换你的数据要慢。(可能慢得可以忽略不计,但不会更快。)

import matplotlib.pyplot as plt
import numpy as np

# Generate data to match yours...
y = 60 * np.random.random(300) - 20
x = 60 * (np.random.random(300) - 0.5)
x[x < 0] += 360

fig, (ax1, ax2) = plt.subplots(ncols=2, sharey=True)
fig.subplots_adjust(wspace=0)

ax1.spines['right'].set_visible(False)
ax2.spines['left'].set_visible(False)
ax1.tick_params(right=False)
ax2.tick_params(left=False)
for label in ax2.get_yticklabels():
    label.set_visible(False)

ax1.plot(x[x > 180], y[x > 180], 'b.')
ax2.plot(x[x <= 180], y[x <= 180], 'b.')

ax2.set_xticks(ax2.get_xticks()[1:])

plt.show()

在此处输入图像描述

于 2011-11-23T22:28:20.943 回答