2016-04-23 1 views
2

Essayer de créer une rose des vents à Matplotlib en utilisant des lignes au lieu de barres. En d'autres termes, je voudrais quelque chose comme ceci (qui a été créé avec Gnuplot) où les lignes ont une épaisseur constante sur toute la longueur et s'étendent de l'origine à la vitesse du vent le long du radial (le rouge est l'observation la plus indigo est pic, et les plus âgés obs deviennent plus sombres à mesure qu'ils vieillissent):Matplotlib Parcelle polaire avec lignes

wind rose 1

Le plus proche que je suis en mesure de venir est ce (s'il vous plaît ignorer toutes les différences sauf pour les lignes):

wind rose 2

Tout ce que j'ai essayé j'ai s tracée d'une manière qui "sort" de l'origine - que ce soit des barres, des lignes, des flèches, peu importe. Voici la ligne de parcelle:

bars = ax.bar(wind_direction, wind_speed, width=.075, linewidth=0.1, edgecolor='black', zorder=3) 

SOLUTION:

Solution

Voici le code complet pour créer l'intrigue souhaitée (juste au-dessus de cette ligne) grâce à la solution de @cphlewis. Mon erreur en essayant d'utiliser plot était de tracer toutes les données en une seule commande, plutôt que « n » nombre de parcelles (tracer chaque ligne individuellement.)

#! /usr/bin/env python2.6 
# -*- coding: utf-8 -*- 

import csv 
import numpy as np 
import matplotlib.pyplot as plt 

bar_colors  = ['#333333', '#444444', '#555555', '#666666', '#777777', '#888888', '#999999', 'red'] 
data_source = '/Users/username/Dropbox/Public/charts.csv' 
num_obs  = 8 
final_data  = [] 
wind_direction = [] 
wind_speed  = [] 

# Get the data. 
data_file = open(data_source, "r") 
csv_data = csv.reader(data_file, delimiter=',') 
[final_data.append(item) for item in csv_data] 
data_file.close() 

# Grab the column headings for the labels, then delete the row from final_data. 
xlabel = final_data[0][24] 
ylabel = final_data[0][25] 
final_data.pop(0) 

# Create lists of data to plot (string -> float). 
[wind_direction.append(float(item[24])) for item in final_data] 
[wind_speed.append(float(item[25])) for item in final_data] 

# Make them the desired length based on num_obs. 
wind_direction = wind_direction[len(wind_direction)-num_obs:len(wind_direction)] 
wind_speed  = wind_speed[len(wind_speed)-num_obs:len(wind_speed)] 

# Polar plots are in radians (not degrees.) 
wind_direction = np.radians(wind_direction) 


wind = zip(wind_direction, wind_speed, bar_colors) # polar(theta,r) 


# Customizations. 
plt.figure(figsize=(3, 3)) # Size 
ax = plt.subplot(111, polar=True) # Create subplot 
plt.grid(color='#888888') # Color the grid 
ax.set_theta_zero_location('N') # Set zero to North 
ax.set_theta_direction(-1) # Reverse the rotation 
ax.set_xticklabels(['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'], color='#666666', fontsize=8) # Customize the xtick labels 
ax.spines['polar'].set_visible(False) # Show or hide the plot spine 
ax.set_axis_bgcolor('#111111') # Color the background of the plot area. 

# Create the plot. 
# Note: zorder of the plot must be >2.01 for the plot to be above the grid (the grid defaults to z=2.) 
for w in wind: 
    ax.plot((0, w[0]), (0, w[1]), color=w[2], linewidth=2, zorder=3) 

# Right-size the grid (must be done after the plot), and customize the tick labels. 
if max(wind_speed) <= 5: 
    ax.yaxis.set_ticks(np.arange(1, 5, 1)) 
    ax.set_rgrids([1, 2, 3, 4, 5], angle=67, color='#FFFFFF', horizontalalignment='left', verticalalignment='center', fontsize=8) 
elif 5 < max(wind_speed) <= 10: 
    ax.yaxis.set_ticks(np.arange(2, 10, 2)) 
    ax.set_rgrids([2, 4, 6, 8, 10], angle=67, color='#FFFFFF', horizontalalignment='left', verticalalignment='center', fontsize=8) 
elif 10 < max(wind_speed) <= 20: 
    ax.yaxis.set_ticks(np.arange(5, 20, 5)) 
    ax.set_rgrids([5, 10, 15, 20], angle=67, color='#FFFFFF', horizontalalignment='left', verticalalignment='center', fontsize=8) 
elif 20 < max(wind_speed) <= 50: 
    ax.yaxis.set_ticks(np.arange(10, 50, 10)) 
    ax.set_rgrids([10, 20, 30, 40, 50], angle=67, color='#FFFFFF', horizontalalignment='left', verticalalignment='center', fontsize=8) 
elif 50 < max(wind_speed): 
    plt.text(0.5, 0.5, u'Holy crap!', color='white', horizontalalignment='center', verticalalignment='center', transform=ax.transAxes, bbox=dict(facecolor='red', alpha=0.5)) 

# Plot circles for current obs and max wind. 
fig = plt.gcf() 
max_wind_circle = plt.Circle((0, 0), max(wind_speed), transform=ax.transData._b, fill=False, edgecolor='indigo', linewidth=2, alpha=1, zorder=9) 
fig.gca().add_artist(max_wind_circle) 
last_wind_circle = plt.Circle((0, 0), wind_speed[num_obs-1], transform=ax.transData._b, fill=False, edgecolor='red', linewidth=2, alpha=1, zorder=10) 
fig.gca().add_artist(last_wind_circle) 

# If latest obs is a speed of zero, plot something that we can see. 
if wind_speed[num_obs-1] == 0: 
    zero_wind_circle = plt.Circle((0, 0), 0.1, transform=ax.transData._b, fill=False, edgecolor='red', alpha=1) 
    fig.gca().add_artist(zero_wind_circle) 

# Save it to a file. 
plt.savefig('/Users/username/Desktop/wind.png', facecolor='black', edgecolor='none') 
+0

Pas encore un exemple complet, comme vous appelez charts.csv – cphlewis

Répondre

1

Votre vraie question est, comment tracer une polaire intrigue avec des lignes au lieu de barres? Réponse: plot. Un exemple minimal et complet de le faire:

#! /usr/bin/env python2.6 
# -*- coding: utf-8 -*- 

import csv 
import numpy as np 
import matplotlib.pyplot as plt 

bar_colors  = ['#333333', '#444444', '#555555', '#666666', '#777777', '#888888', '#999999', '#AA0000'] 
num_obs  = len(bar_colors) 

# Make up some data 
wind_direction = (2*3.14)*(np.random.random_sample(num_obs)) 
wind_speed = 5 * np.random.random_sample(num_obs) 
wind = zip(wind_direction, wind_speed, bar_colors) # polar(theta,r) 

# Polar plotting 
fig = plt.figure(figsize=(3, 3)) # Size 
ax = plt.subplot(111, polar=True) # Create subplot 
plt.grid(color='#888888') # Color the grid 
ax.set_theta_zero_location('N') # Set zero to North 

for w in wind: 
    #ax.plot(wind_speed, wind_direction, c = bar_colors, zorder = 3) 
    ax.plot((0, w[0]), (0, w[1]), c = w[2], zorder = 3) 

fig.show() 

enter image description here

+0

brillant. Quand j'ai essayé de tracer avec 'plot', MPL connectait les points. Fait pour un intrigue intéressante, mais pas très utile. Votre exemple, bien que partiel, était plug and play. À votre santé! – DaveL17

+0

C'est exactement le comportement que 'plot' a dans d'autres transformations - si vous lui donnez une série de valeurs 'theta' et' r', il les connecte, tout comme 'plot' connecte une série de' x' et 'y' valeurs. – cphlewis

+0

Droite. Cela a un sens parfait. À présent. Merci encore. – DaveL17