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>You could increase the <code>density</code> parameter to get more smooth color transitions,
but then use the <code>start_points</code> parameter to reduce your overall clutter.
The start_points parameter allows you to explicity choose the location and
number of trajectories to draw.  It overrides the default, which is to plot
as many as possible to fill up the entire plot.</p>

<p>But first you need one little fix to your existing code:
According to the <a href="http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.streamplot" rel="nofollow">streamplot</a> documentation, the X and Y args should be 1d arrays, not 2d arrays as produced by mgrid.
It looks like passing in 2d arrays is supported, but it is undocumented
and it is currently not compatible with the start_points parameter.</p>

<p>Here is how I revised your X, Y, Vx, Vy and speed:</p>

<pre><code># Grid
num_steps = 11
Y = np.linspace(-25, 25, num_steps)
X = np.linspace(0, 25, num_steps)
Ygrid, Xgrid = np.mgrid[-25:25:(num_steps * 1j), 0:25:(num_steps * 1j)]
Vx = Bx(Xgrid, Ygrid)
Vy = By(Xgrid, Ygrid)
speed = np.hypot(Vx, Vy)
lw = 3*speed / speed.max()+.5
</code></pre>

<p>Now you can explicitly set your <code>start_points</code> parameter.  The start points are actually
"seed" points.  Any given stream trajectory will grow in <em>both</em> directions
from the seed point.  So if you put a seed point right in the center of
the example plot, it will grow both up and down to produce a vertical
stream line.</p>

<p>Besides controlling the <em>number</em> of trajectories, using the
<code>start_points</code> parameter also controls the <em>order</em> they are
drawn.  This is important when considering how trajectories terminate.
They will either hit the border of the plot, or they will terminate if
they hit a cell of the plot that already has a trajectory.  That means
your first seeds will tend to grow longer and your later seeds will tend
to get limited by previous ones.  Some of the later seeds may not grow
at all.  The default seeding strategy is to plant a seed at every cell,
which is pretty obnoxious if you have a high density.  It also orders
them by planting seeds first along the plot borders and spiraling inward.
This may not be ideal for your particular case.  I found a very simple
strategy for your example was to just plant a few seeds between those
two points of zero velocity, y=0 and x from -10 to 10. Those trajectories
grow to their fullest and fill in most of the plot without clutter.</p>

<p>Here is how I create the seed points and set the density:</p>

<pre><code>num_streams = 8
stptsy = np.zeros((num_streams,), np.float)
stptsx_left = np.linspace(0, -10.0, num_streams)
stptsx_right = np.linspace(0, 10.0, num_streams)
stpts_left = np.column_stack((stptsx_left, stptsy))
stpts_right = np.column_stack((stptsx_right, stptsy))
density = (3,6)
</code></pre>

<p>And here is how I modify the calls to <code>streamplot</code>:</p>

<pre><code>strm = ax0.streamplot(X, Y, Vx, Vy, color=speed, linewidth=lw, density=density,
                  cmap=plt.cm.jet, start_points=stpts_right)
ax0.streamplot(-X, Y, -Vx, Vy, color=speed, linewidth=lw,density=density,
                  cmap=plt.cm.jet, start_points=stpts_left)
</code></pre>

<p>The result basically looks like the original, but with smoother color transitions and only 15 stream lines.  (sorry no reputation to inline the image)</p>

python numpy matplotlib