Matplotlib: How to increase colormap/linewidth quality in streamplot?
<p>I have the following code to generate a streamplot based on an <code>interp1d</code>-Interpolation of discrete data:</p>

<pre><code>import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as colors
from scipy.interpolate import interp1d

# CSV Import
a1array=pd.read_csv('a1.csv', sep=',',header=None).values
rv=a1array[:,0]
a1v=a1array[:,1]
da1vM=a1array[:,2]
a1 = interp1d(rv, a1v)
da1M = interp1d(rv, da1vM)

# Bx and By vector components
def bx(x ,y):
    rad = np.sqrt(x**2+y**2)
    if rad == 0:
        return 0
    else:
        return x*y/rad**4*(-2*a1(rad)+rad*da1M(rad))/2.87445E-19*1E-12

def by(x ,y):
    rad = np.sqrt(x**2+y**2)
    if rad == 0:
        return 4.02995937E-04/2.87445E-19*1E-12
    else:
        return -1/rad**4*(2*a1(rad)*y**2+rad*da1M(rad)*x**2)/2.87445E-19*1E-12

Bx = np.vectorize(bx, otypes=[np.float])
By = np.vectorize(by, otypes=[np.float])

# Grid
num_steps = 11
Y, X = np.mgrid[-25:25:(num_steps * 1j), 0:25:(num_steps * 1j)]
Vx = Bx(X, Y)
Vy = By(X, Y)
speed = np.sqrt(Bx(X, Y)**2+By(X, Y)**2)
lw = 2*speed / speed.max()+.5

# Star Radius
circle3 = plt.Circle((0, 0), 16.3473140, color='black', fill=False)

# Plot
fig0, ax0 = plt.subplots(num=None, figsize=(11,9), dpi=80, facecolor='w', edgecolor='k')
strm = ax0.streamplot(X, Y, Vx, Vy, color=speed, linewidth=lw,density=[1,2], cmap=plt.cm.jet)
ax0.streamplot(-X, Y, -Vx, Vy, color=speed, linewidth=lw,density=[1,2], cmap=plt.cm.jet)
ax0.add_artist(circle3)
cbar=fig0.colorbar(strm.lines,fraction=0.046, pad=0.04)
cbar.set_label('B[GT]', rotation=270, labelpad=8)
cbar.set_clim(0,1500)
cbar.draw_all()
ax0.set_ylim([-25,25])
ax0.set_xlim([-25,25])
ax0.set_xlabel('x [km]')
ax0.set_ylabel('z [km]')
ax0.set_aspect(1)
plt.title('polyEos(0.05,2), M/R=0.2, B_r(0,0)=1402GT', y=1.01)
plt.savefig('MR02Br1402.pdf',bbox_inches=0)
plt.show(fig0)
</code></pre>

<p>I uploaded the csv-file here if you want to try some stuff  <a href="https://www.dropbox.com/s/4t7jixpglt0mkl5/a1.csv?dl=0">https://www.dropbox.com/s/4t7jixpglt0mkl5/a1.csv?dl=0</a>.
Which generates the following plot:
<a href="http://i.stack.imgur.com/pYGPi.png"><img src="http://i.stack.imgur.com/pYGPi.png" alt="StreamPlot"></a></p>

<p>I am actually pretty happy with the result except for one small detail, which I can not figure out: If one looks closely the linewidth and the color change in rather big steps, which is especially visible at the center:</p>

<p><a href="http://i.stack.imgur.com/zG67s.png"><img src="http://i.stack.imgur.com/zG67s.png" alt="Problem"></a></p>

<p>Is there some way/option with which I can decrease the size of this steps to especially make the colormap smother?</p>

<p>I think your best bet is to use a colormap other than jet. Perhaps <code>cmap=plt.cmap.plasma</code>.</p>

<p><a href="http://i.stack.imgur.com/Vw0Gc.png" rel="nofollow"><img src="http://i.stack.imgur.com/Vw0Gc.png" alt="The same graph with the plasma colormap"></a></p>

<p>Wierd looking graphs obscure understanding of the data.</p>

<p>For data which is ordered in some way, like by the speed vector magnitude in this case, uniform sequential colormaps will always look smoother. The brightness of sequential maps varies monotonically over the color range, removing large percieved color changes over small ranges of data. The uniform maps vary linearly over their whole range which makes the main features in the data much more visually apparent.</p>

<p><img src="http://matplotlib.org/_images/lightness_00.png" alt="Perceptually Uniform Sequential Color Maps"></p>

<p>The jet colormap spans a very wide variety of brightnesses over its range with in inflexion in the middle. This is responsible for the particularly egregious red to blue transition around the center region of your graph.</p>

<p><img src="http://matplotlib.org/_images/lightness_05.png" alt="Jet and other Non-Sequential Color Maps"></p>

<p><a href="http://matplotlib.org/users/colormaps.html" rel="nofollow">The matplotlib user guide on choosing a color map</a> has a few recomendations for about selecting an appropriate map for a given data set.</p>

<p>I dont think there is much else you can do to improve this by just changing parameters in your plot.</p>

<p>The streamplot divides the graph into cells with <code>30*density[x,y]</code> in each direction, at most one streamline goes through each cell. The only setting which directly increases the number of segments is the density of the grid matplotlib uses. Increasing the Y density will decrease the segment length so that the middle region may transition more smoothly. The cost of this is an inevitable cluttering of the graph in regions where the streamlines are horizontal. </p>

<p>You could also try to normalise the speeds differently so the the change is artifically lowered in near the center. At the end of the day though it seems like it defeats the point of the graph. The graph should provide a useful view of the data for a human to understand. Using a colormap with strange inflexions or warping the data so that it looks nicer removes some understanding which could otherwise be obtained from looking at the graph.</p>

<p>A more detailed discussion about the issues with colormaps like jet can be found on this <a href="https://mycarta.wordpress.com/2012/05/12/the-rainbow-is-dead-long-live-the-rainbow-part-1/" rel="nofollow">blog</a>.</p>

python numpy matplotlib