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

放肆的年华 提交于 2021-01-29 14:37:51

问题


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')

回答1:


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.



来源:https://stackoverflow.com/questions/58205213/matplotlibs-rstride-cstride-messes-up-color-maps-in-plot-surface-3d-plot

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