Tout ce que j'utilise Matplotlib, des diagrammes en flash Open-Flash ou d'autres graphiques, j'ai toujours terminé de trouver un moyen de définir des limites et des intervalles d'échelle X / Y puisque les produits ne sont pas assez intelligents (ou pas du tout ... )
Essayez simplement ceci dans pylab (ipythton -pylab) pour comprendre ce que je veux dire: p> Vous verrez juste et vide la grille de cadre masquant les 2 lignes horizontales sous C'est ses bordures supérieures et inférieures. P> Je me demande s'il y a un algorithme autour (que je peux porter à Python) pour définir des limites et des étapes clôturées élégamment supérieures et inférieures et de calculer toutes les valeurs montrant l'épaisseur X. P> < P> Par exemple, disons que j'ai 475 mesures comme (une toutes les 5 minutes) et p> Ma suggestion pour ce cas particulier pourrait être de définir: P> et une tique sur mais qu'en est-il de seulement 20 mesures sur 20 jours avec (datetétime, température) code> comme
(x, y) code> avec p>
26.4 <= y__scale <= 28.4 code> avec un épaisseur tous les
.2 code> p> p> P>
blockQquote>
x_scale code> tous les 12 éléments (une fois par heure). p>
-21.5
4 Réponses :
Ce qui suit est ce que j'ai utilisé pendant des années, ce qui est simple et qui fonctionne assez bien. Pardonne-moi pour que cela soit c mais traduire en python ne devrait pas être difficile.
La fonction suivante est nécessaire et provient des gemmes graphiques Volume 1. P>
//Input parameters double AxisStart = 26.5; double AxisEnd = 28.3; double NumTicks = 10; double AxisWidth; double NewAxisStart; double NewAxisEnd; double NiceRange; double NiceTick; /* Check for special cases */ AxisWidth = AxisEnd - AxisStart; if (AxisWidth == 0.0) return (0.0); /* Compute the new nice range and ticks */ NiceRange = NiceNumber(AxisEnd - AxisStart, 0); NiceTick = NiceNumber(NiceRange/(NumTicks - 1), 1); /* Compute the new nice start and end values */ NewAxisStart = floor(AxisStart/NiceTick)*NiceTick; NewAxisEnd = ceil(AxisEnd/NiceTick)*NiceTick; AxisStart = NewAxisStart; //26.4 AxisEnd = NewAxisEnd; //28.4
Plus j'utilise cela, plus je trouve cela vraiment intelligent, merci pour le partage.
Je signalez ici ma version Python de Code ci-dessus si elle peut être de toute aide pour une personne: Utiliser comme: p> Ajoutez également un portage JavaScript: P> function nice_number(value, round_){
//default value for round_ is false
round_ = round_ || false;
// :latex: \log_y z = \frac{\log_x z}{\log_x y}
var exponent = Math.floor(Math.log(value) / Math.log(10));
var fraction = value / Math.pow(10, exponent);
if (round_)
if (fraction < 1.5)
nice_fraction = 1.
else if (fraction < 3.)
nice_fraction = 2.
else if (fraction < 7.)
nice_fraction = 5.
else
nice_fraction = 10.
else
if (fraction <= 1)
nice_fraction = 1.
else if (fraction <= 2)
nice_fraction = 2.
else if (fraction <= 5)
nice_fraction = 5.
else
nice_fraction = 10.
return nice_fraction * Math.pow(10, exponent)
}
function nice_bounds(axis_start, axis_end, num_ticks){
//default value is 10
num_ticks = num_ticks || 10;
var axis_width = axis_end - axis_start;
if (axis_width == 0){
axis_start -= .5
axis_end += .5
axis_width = axis_end - axis_start
}
var nice_range = nice_number(axis_width);
var nice_tick = nice_number(nice_range / (num_ticks -1), true);
var axis_start = Math.floor(axis_start / nice_tick) * nice_tick;
var axis_end = Math.ceil(axis_end / nice_tick) * nice_tick;
return {
"min": axis_start,
"max": axis_end,
"steps": nice_tick
}
}
Vous pouvez utiliser math.log10 () code> dans javascript.
Vous trouverez ci-dessous mon code Python pour calculer automatiquement les ticks, il a besoin de la plage de données et du nombre maximum de tiques.
Par exemple: P>
def auto_tick(data_range, max_tick=10, tf_inside=False): """ tool function that automatically calculate optimal ticks based on range and the max number of ticks :param data_range: range of data, e.g. [-0.1, 0.5] :param max_tick: max number of ticks, an interger, default to 10 :param tf_inside: True/False if only allow ticks to be inside :return: list of ticks """ data_span = data_range[1] - data_range[0] scale = 10.0**np.floor(np.log10(data_span)) # scale of data as the order of 10, e.g. 1, 10, 100, 0.1, 0.01, ... list_tick_size_nmlz = [5.0, 2.0, 1.0, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01] # possible tick sizes for normalized data in range [1, 10] tick_size_nmlz = 1.0 # initial tick size for normalized data for i in range(len(list_tick_size_nmlz)): # every loop reduces tick size thus increases tick number num_tick = data_span/scale/list_tick_size_nmlz[i] # number of ticks for the current tick size if num_tick > max_tick: # if too many ticks, break loop tick_size_nmlz = list_tick_size_nmlz[i-1] break tick_size = tick_size_nmlz * scale # tick sizse for the original data ticks = np.unique(np.arange(data_range[0]/tick_size, data_range[1]/tick_size).round())*tick_size # list of ticks if tf_inside: # if only allow ticks within the given range ticks = ticks[ (ticks>=data_range[0]) * (ticks<=data_range[1])] return ticks
et voici la version de @uesp Réponse dans TypeScript / JavaScript ES6:
function niceNumber(value: number, round = false) { const exponent = Math.floor(Math.log10(value)); const fraction = value / Math.pow(10, exponent); let niceFraction: number; if (round) { if (fraction < 1.5) { niceFraction = 1.0; } else if (fraction < 3.0) { niceFraction = 2.0; } else if (fraction < 7.0) { niceFraction = 5.0; } else { niceFraction = 10.0; } } else { if (fraction <= 1.0) { niceFraction = 1.0; } else if (fraction <= 2.0) { niceFraction = 2.0; } else if (fraction <= 5.0) { niceFraction = 5.0; } else { niceFraction = 10.0; } } return niceFraction * Math.pow(10, exponent); } export function calcTicks(minValue: number, maxValue: number, ticksCount: number) { const range = niceNumber(maxValue - minValue); const tickValue = niceNumber(range / (ticksCount - 1), true); const ticks: number[] = []; for (let i = 0; i < ticksCount; i++) { ticks.push(minValue + tickValue * i); } return ticks; }