4
$\begingroup$

To provide a bit of background, I have a set of wind flow data from a two-dimensional computational fluid dynamics simulation in an urban environment. The data that are returned from the simulation are two matrices, u and v, that highlight the wind flow velocity in the horizontal and vertical directions of the plane:

A false-color image of the u matrix: the wind flow in the horizontal direction. A false-color image of the v matrix: the wind flow in the vertical direction.

To briefly go over the above images, the first is a false-color plot of the u matrix. In this case, warm colors correspond to regions of high wind flow velocities in the horizontal direction (going from right to left) while cooler colors correspond to either regions with low wind flow velocities or those velocities going in the opposite direction. The light blue polygons in the image are the buildings, which have no horizontal wind flow velocity.

The second image is a false-color plot of the v matrix. In a similar fashion as before, warm colors correspond to regions of high wind flow velocities in the vertical direction (going from top to bottom) while cooler colors correspond to either regions with low wind flow velocities or those velocities going in the opposite direction. The yellow-green polygons in the image are the buildings, which have no vertical wind flow velocity.

As I have done in the past for my computational fluid dynamics plots, I combined both of these matrices into a form that could be understood by Mathemtica as a ListStreamPlot. That is, for each spatial location in my u and v matrix, I pass out an array of values: {{{x_location,y_location},{u_value,v_value}},...}. For this particular simulation, I only considered rows of u and v that were sandwiched between the buildings; a copy of the data contained within a Mathematica notebook can be obtained from here. When I went to go and make a ListStreamPlot,

ListStreamPlot[data, AspectRatio -> 0.5, StreamPoints -> Fine, PerformanceGoal -> "Quality", StreamColorFunction -> "Rainbow"]

however, I ended up with far fewer stream lines than I have been accustomed to seeing:

A streamline plot of the wind flow data

Consequently, my question is this: how can I ensure that Mathematica includes more streamlines in the plot? (It is apparent, from the above images of u and v, that there should be more streamlines that could be generated.) Moreover, I would like to ensure that the arrows on the ListStreamPlot are included in the final visualization along with the chosen color scheme; the latter of these desires seems to be ignored in my ListStreamPlot, which leads me to believe that there might need to be some post-processing done to the data.

Also, as a final note, I have already looked at the discussion here and the highest rated response from Jens has not worked in the context of my data.

$\endgroup$
6
  • 1
    $\begingroup$ What in my answer to this question did not work for you? $\endgroup$
    – Jens
    May 15, 2014 at 2:45
  • $\begingroup$ I appreciate your prompt reply, Jens! As for your code, it works fine for StreamPlots. When I went to modify it for a ListStreamPlot, i.e., changing RandomReal to RandomInteger along with the domain of the random seed points, Mathematica returned the following error: ListStreamPlot::vfldata: data is not a valid vector field dataset or a valid list of datasets. My guess is that I have improperly modified your function call and would be grateful for any suggestions that you might have. $\endgroup$
    – isledge
    May 15, 2014 at 3:05
  • 1
    $\begingroup$ Actually, the problem is that Mathematica's default streamline plotting functions don't work well when the aspect ratio of the domain doesn't match that of the plot, as raised in this question. My solution there assumes that the plot has an aspect ratio of 1, but it should be possible to modify it for a 0.5 aspect ratio plot. $\endgroup$
    – user484
    May 15, 2014 at 3:25
  • $\begingroup$ Rahul, as per my comment below and this image: i.stack.imgur.com/7BvgV.png, it would appear that you are correct. Since it's not immediately obvious to me how to update your function to the case of ListStreamPlots, would you mind posting a solution with the modifications? $\endgroup$
    – isledge
    May 15, 2014 at 3:43
  • $\begingroup$ As an aside, a quick and dirty hack is to just resample my domain. In particular, instead of spanning the range [1,583]x[1,30], I can simply select every 15th point along the horizontal axis such that my new domain becomes [1,38]x[1,30]; this leads to many more stream lines, as you highlighted in your post, and also a much less uniform coloration of the stream lines. Still, it would be nice to have a more automated solution, like the one that you proposed, that wouldn't require throwing away data. $\endgroup$
    – isledge
    May 15, 2014 at 3:55

2 Answers 2

5
$\begingroup$

Here is a simple adaptation of my answer mentioned in the question:

data = Table[{-1 - x^2 + y, 1 + x - y^2}, {x, -3, 3, .2}, {y, -3, 
    3, .2}];

t = Map[ListStreamPlot[data, DataRange -> {{-3, 3}, {-3, 3}}, 
     StreamStyle -> "Line", 
     StreamPoints -> RandomReal[{-3, 3}, {#, 2}], ImageSize -> 500] &,
    ConstantArray[50, 20]];

Show[t]

plot

I used a simple data set data from the docs, and added the appropriate DataRange to the ListStreamPlot.

In order to try this with your own data, just do a single ListStreamPlot first and make sure the data range is correct. With the data range as above, RandomInteger would make no sense. But as I mentioned in the other answer, you can replace RandomInteger by some function of your choice. It just has to be constructed to fit the desired amount of lines into the plot range.

To include the color and arrow information, the following works:

t = Map[ListStreamPlot[data, DataRange -> {{-3, 3}, {-3, 3}}, 
     StreamColorFunction -> "Rainbow", 
     StreamPoints -> RandomReal[{-3, 3}, {#, 2}], ImageSize -> 500] &,
    ConstantArray[20, 20]];

Show[t]

plot2

Here I added the StreamColorFunction option and removed the line style for the stream lines. Also, to make the arrows recognizable, I reduced the number of stream lines (that's determined by the arguments of ConstantArray[20, 20]).

Edit: the actual data

After looking at the actual data linked in the question, it does look like there is something wrong with the way ListStreamPlot colors the lines. Strangely, this can be fixed by just omitting one element of the list data. It doesn't seem to matter which element I omit. So here I leave out the last element, and everything works. It takes quite long to make the plot because of the large data file:

t = Map[ListStreamPlot[Most[data], StreamColorFunction -> "Rainbow", 
     StreamPoints -> 
      Transpose[{RandomInteger[{1, 583}, #], 
        RandomInteger[{1, 29}, #]}], ImageSize -> 500] &, 
   ConstantArray[20, 20]];
Show[t, AspectRatio -> .5, PlotRange -> {{1, 583}, {1, 29}}]

plot3

In addition to adding the different AspectRatio, I also specified the PlotRange according to the data.

$\endgroup$
2
  • $\begingroup$ Jens, your result partly works for my data: i.stack.imgur.com/VvJqj.png What's peculiar is that it appears that the StreamColorFunction is not working properly. This is likely related to the plot aspect issue that Rahul Narain raised, as when I set AspectRatio -> Automatic, the lines in the plot come across as mostly horizontal, which explains why they are just colored purple: i.stack.imgur.com/7BvgV.png $\endgroup$
    – isledge
    May 15, 2014 at 3:40
  • $\begingroup$ @isledge Yes, there's something wrong with ColorFunction handling, but I discovered an apparent work-around. See my update. I can't say why it works, it's mysterious why this coloring didn't work with the original data you provided. I checked your data and saw nothing immediately untoward in there - except that they are very large and therefore not much fun to wait for the plots... $\endgroup$
    – Jens
    May 15, 2014 at 4:47
1
$\begingroup$

Well, right now I have a solution without correct colouring. Trying to get the colour map right has led me into all sorts of trouble, and there's still new problems that I might have to ask another question about. But here's what works so far.

{{x, y}, {u, v}} = Transpose[data, {3, 1, 2}];
{{x0, x1}, {y0, y1}} = Through[{Min, Max}[#]] & /@ {x, y};
aspectRatio = 1/2;
scale = {1/(x1 - x0), aspectRatio/(y1 - y0)};
Show[
 ListStreamPlot[Transpose[{scale {x, y}, scale {u, v}}, {2, 3, 1}], 
   AspectRatio -> aspectRatio, StreamPoints -> Fine, ImageSize -> 500] 
  /. Arrow[pts_] :> Arrow[#/scale & /@ pts], 
 PlotRange -> {{x0, x1}, {y0, y1}}]

enter image description here

Note that you can't just say StreamColorFunction -> "Rainbow" on this plot, because then it'll choose colours based on the norms of the scaled vectors we've fed into ListStreamPlot, and those are not proportional to the norms of the original vectors because the scaling is nonuniform.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.