简体   繁体   中英

Matplotlib's rstride, cstride messes up color maps in plot_surface 3D plot?

I have a large dataset consisting of 3595.csv files containing 1252 pairs of x,y tuples. Each file represents a time frame. These are plottet using plot_surf() . I found out, that my data will be sieved (in regards to the files, or time frames) by default with a step of 10 when plotting my data, which is why I need to specify rstride=1, cstride=1 in my artist in order to plot everything.

When I did this, I accidentally discovered the solution to a problem I faced earlier: By default the plot showed regular gaps in the surface, which are not a consequence of the data provided. Further, the colormap "jet" was not used correctly. These issues can be seen in the plot below.

失败的情节

Compare this to how the plot should actually look like:

在此处输入图像描述

All I changed in my code was the args rstride and cstride of the plot_surf function, which was accompanied by a very, very long execution time. But I did get the correct result.

So my question is: What gives? Why does this work suddenly? Why won't the colormap/plot without gaps work for the default stride?

Here's my code:

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
import matplotlib.ticker as tkr
import numpy as np
import glob
import pandas as pd

Files = glob.glob('*.xy')
dtime = 1

Z = np.array([pd.read_csv(file,
                          decimal=',',
                          delim_whitespace=True,
                          header=None,
                          names=['2theta','I'])['I']
                          for num, file in enumerate(Files)
                          if num < len(Files)])



X = np.array([pd.read_csv(Files[0],
                          decimal=',',
                          delim_whitespace=True,
                          header=None,
                          names=['2theta','I'])['2theta']])

Y = np.array([[t*dtime for t in range(0,len(Files))]])

X, Y = np.meshgrid(X, Y)


fig = plt.figure(figsize=(7,5))
ax = fig.gca(projection='3d')


# Plot the surface.
surf = ax.plot_surface(X,
                       Y,
                       Z,
                       cmap=cm.jet,
                       rstride=1,
                       cstride=1,
                       vmin=np.amin(Z),
                       vmax=np.amax(Z),
                       linewidth=0,
                       antialiased=True)

ax.set_ylabel(r'$t \quad / \quad$ s',
              labelpad=7)

ax.set_xlabel(r'$2\theta \quad / \quad °$',
              labelpad=7)

ax.set_zlabel('$I$ in a.u.',
              labelpad=7)


ax.xaxis.set_major_locator(tkr.AutoLocator())
ax.yaxis.set_major_locator(tkr.AutoLocator())
ax.zaxis.set_major_locator(tkr.AutoLocator())

ax.get_xaxis().get_major_formatter().set_useOffset(True)
ax.get_xaxis().get_major_formatter().set_useOffset(True)
ax.get_xaxis().get_major_formatter().set_useOffset(True)

fig.colorbar(surf, shrink=0.7, aspect=20, pad=0.12)

plt.tight_layout()
plt.savefig('3D.png', dpi=300, bbox='tight')

Have a look at the docs . In particular this:

The rstride and cstride kwargs set the stride used to sample the input data to generate the graph. If 1k by 1k arrays are passed in, the default values for the strides will result in a 100x100 grid being plotted. Defaults to 10. Raises a ValueError if both stride and count kwargs (see next section) are provided.

This should answer your question: if rstride and cstride are not 1, not all the points are used to draw the surface.
This saves time, because the more the points to plot, the longer the time needed to compute the plot.
But at the same time, if your surface has a high variability, skipping 9 points over 10 in the plot will result in a different picture.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM