semilogx() - x-axis - Increase scaling for lower frequencies - compress higher frequencies

7 vues (au cours des 30 derniers jours)
Jo
Jo le 26 Août 2023
Commenté : dpb le 26 Août 2023
Hello, maybe someone can help me out here?
I am plotting 6 filtered sequences which works fine so far.
My Problem is the scaling on the x-axis:
I just can't figure out how to adjust the scaling on the x-axis for the frequencies so that all six sequences have the same size.
The limits are fine but the scaling is off: My target plot should look like this where each filtered signal has the same width.
In my first Plot the scaling works perfectly! But I cant get it to work on my filtered spectrum
In both cases I am using semilogx()
Here is a small snippet (somewhere I have to scale, but where?)
Sorry for the simple and dumb question but I just downloaded matlab2023 this night and never touched it before.
And yes I searched for quite a while for an answer... :)
frequencies = (0:N-1) * frequency_resolution;
...
magnitudes_dB = cellfun(@(x) 20 * log10(abs(x) / N), filtered_signals, 'UniformOutput', false);
...
mask = (frequencies >= 20) & (frequencies <= 6000);
...
figure;
hold on; % Enable plotting multiple lines on the same graph
for i = 1:numel(rcf_filters)
semilogx(frequencies(mask), magnitudes_dB{i}(mask), 'DisplayName', labels{i});
end

Réponse acceptée

dpb
dpb le 26 Août 2023
The issue isn't the plotting scaling; it's the data content. Each of the triangular-looking traces in the reference plot goes from a range that is 2X upper/lower range of previous offset by 10^n, n=0,1,2,... Hence, each trace is essentially the same except offset.
Your six traces vary in width by 2x rather than having the same frequency range from min to max. The three largest that can read are 2-6K, 1-3K, 0.5-1.5K, ... each range 2X the previous. That's just not the same as the desired.
You didn't give how were derived, but the problem isn't in the plotting but how the signals were generated if were to mimic the other figure.
  2 commentaires
Jo
Jo le 26 Août 2023
Déplacé(e) : Voss le 26 Août 2023
Wow thank you, you were right. the data was the problem.. The data was messed up.I would have searched more hours if you hadn't pointed it out.
I went back to the start and loaded up one of my first tries from today.
I think the script is doing the correct stuff as far I can tell! This looks helpful to to configure the raised-cosine-filters which I use:
Context:
RCFxxx are the filter functions with corresponding frequency Center. My goal is to tune the RCF-Generation-Process to get a good overlapping between them.
diracSequence is a generated pulse sequence. In this case 2Sec and 44100 Hz SampingFrequency.
The diracSequence is transformed to frequency domain and each RCF is applied to get 6 filtered 'sequences'.
For completeness here is the approach.
rcf125 = load("RCF\0_RCF125_0.txt");
rcf250 = load("RCF\0_RCF250_0.txt");
rcf500 = load("RCF\0_RCF500_0.txt");
rcf1000 = load("RCF\0_RCF1000_0.txt");
rcf2000 = load("RCF\0_RCF2000_0.txt");
rcf4000 = load("RCF\0_RCF4000_0.txt");
% Load the impulse response of the system (transfer function)
diracSequence = load("DiracSequence\0_diracSequenceIRLength88200.txt");
% Compute the FFT of the impulse response to obtain the frequency domain representation
frequencyDomainSignal = fft(diracSequence);
% Define the RCF filter (4097x1) - Adjust with your specific RCF filter values
rcf_filter125 = rcf125;
rcf_filter250 = rcf250;
rcf_filter500 = rcf500;
rcf_filter1000 = rcf1000;
rcf_filter2000 = rcf2000;
rcf_filter4000 = rcf4000;
% Calculate the number of FFT bins
N = length(frequencyDomainSignal);
% Determine the frequency resolution based on your sampling frequency and FFT size
fs = 44100; % Adjust as needed
frequency_resolution = fs / N;
% Calculate the frequency values corresponding to each FFT bin
frequencies = (0:N-1) * frequency_resolution;
% Interpolate the RCF filter to match the frequency resolution
% You may need to adjust this interpolation method based on your specific RCF filter
desired_frequencies125 = linspace(0, fs/2, length(rcf_filter125));
desired_frequencies250 = linspace(0, fs/2, length(rcf_filter250));
desired_frequencies500 = linspace(0, fs/2, length(rcf_filter500));
desired_frequencies1000 = linspace(0, fs/2, length(rcf_filter1000));
desired_frequencies2000 = linspace(0, fs/2, length(rcf_filter2000));
desired_frequencies4000 = linspace(0, fs/2, length(rcf_filter4000));
interpolated_rcf_filter125 = interp1(desired_frequencies125, rcf_filter125, frequencies);
interpolated_rcf_filter250 = interp1(desired_frequencies250, rcf_filter250, frequencies);
interpolated_rcf_filter500 = interp1(desired_frequencies250, rcf_filter500, frequencies);
interpolated_rcf_filter1000 = interp1(desired_frequencies250, rcf_filter1000, frequencies);
interpolated_rcf_filter2000 = interp1(desired_frequencies250, rcf_filter2000, frequencies);
interpolated_rcf_filter4000 = interp1(desired_frequencies250, rcf_filter4000, frequencies);
% Apply the RCF filter to the frequency domain signal
filtered_signal125 = frequencyDomainSignal .* interpolated_rcf_filter125';
filtered_signal250 = frequencyDomainSignal .* interpolated_rcf_filter250';
filtered_signal500 = frequencyDomainSignal .* interpolated_rcf_filter500';
filtered_signal1000 = frequencyDomainSignal .* interpolated_rcf_filter1000';
filtered_signal2000 = frequencyDomainSignal .* interpolated_rcf_filter2000';
filtered_signal4000 = frequencyDomainSignal .* interpolated_rcf_filter4000';
% Calculate the magnitude in dB
magnitude_dB125 = 20 * log10(abs(filtered_signal125) / N);
magnitude_dB250 = 20 * log10(abs(filtered_signal250) / N);
magnitude_dB500 = 20 * log10(abs(filtered_signal500) / N);
magnitude_dB1000 = 20 * log10(abs(filtered_signal1000) / N);
magnitude_dB2000 = 20 * log10(abs(filtered_signal2000) / N);
magnitude_dB4000 = 20 * log10(abs(filtered_signal4000) / N);
% Create a mask to select the frequency range from 20 Hz to 20,000 Hz
mask = (frequencies >= 20) & (frequencies <= 20000);
% Define custom x-axis frequency labels
customLabels = [20, 100, 1000, 4000, 10000, 20000];
% Plot the magnitude in dB on a logarithmic frequency scale with custom labels
figure;
semilogx(frequencies(mask), magnitude_dB125(mask), 'DisplayName', 'RCF125'); % Specify a label for the legend
hold on; % Enable plotting on the same figure
semilogx(frequencies(mask), magnitude_dB250(mask), 'DisplayName', 'RCF250');
semilogx(frequencies(mask), magnitude_dB500(mask), 'DisplayName', 'RCF500');
semilogx(frequencies(mask), magnitude_dB1000(mask), 'DisplayName', 'RCF1000');
semilogx(frequencies(mask), magnitude_dB2000(mask), 'DisplayName', 'RCF2000');
semilogx(frequencies(mask), magnitude_dB4000(mask), 'DisplayName', 'RCF4000');
xlabel('Frequency (Hz)');
ylabel('Magnitude (dB)');
title('Filtered Transfer Function with RCF');
% Customize the x-axis ticks and labels
xticks(customLabels);
xticklabels({'20', '100', '1k', '4k', '10k', '20k'});
% Set the x-axis limits to start at 20 Hz and end at 20 kHz
xlim([20, 20000]);
legend('Location', 'Best');
grid on;
dpb
dpb le 26 Août 2023
Yes, those appear to be offset by 2F with the width about the center frequency also scaled to match...

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Plot Customization dans Help Center et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by