Matplotlib双X轴对数刻度:手动设上轴后次要刻度适配1.218倍缩放
Solution for Scaling Minor Logarithmic Ticks on Secondary X-axis
Got it, let's work through how to get those minor log ticks on your top X-axis scaled by 1.218 to match your lower axis. Since Matplotlib auto-generates minor ticks for log axes, we need to override that behavior to apply your scaling factor. Here are two approaches depending on your needs:
Approach 1: Static Minor Ticks (Fixed Axis Range)
If your plot's X-axis range won't change after initialization, this quick method works:
import matplotlib.pyplot as plt from matplotlib.ticker import LogLocator, FixedLocator # Example data (replace with your own) x_vals = [10, 50, 100, 500, 1000] y_vals = [2, 4, 6, 8, 10] # Create base plot with log-log axes fig, ax = plt.subplots() ax.loglog(x_vals, y_vals) ax.set_xlabel("Lower X-axis (log10 scale)") ax.set_ylabel("Y-axis") # Add top X-axis with 1.218x scaling top_ax = ax.secondary_xaxis("top", functions=(lambda x: x * 1.218, lambda x: x / 1.218)) top_ax.set_xlabel("Upper X-axis (1.218x lower axis, log10 scale)") # Get minor ticks from lower axis, scale them, and apply to top axis lower_minor_locator = ax.xaxis.get_minor_locator() lower_minor_ticks = lower_minor_locator() # Generate minor tick positions for lower axis scaled_minor_ticks = [tick * 1.218 for tick in lower_minor_ticks] # Set scaled ticks as minor ticks on top axis top_ax.xaxis.set_minor_locator(FixedLocator(scaled_minor_ticks)) plt.tight_layout() plt.show()
How this works:
- We first create the secondary axis using
secondary_xaxis, defining the forward (lower → top) and reverse (top → lower) scaling functions. - We grab the minor tick positions that Matplotlib would use for the lower log axis, multiply each by 1.218, then force the top axis to use these scaled positions as its minor ticks with
FixedLocator.
Approach 2: Dynamic Minor Ticks (Auto-Updates with Axis Range Changes)
If you need the minor ticks to automatically adjust when you pan/zoom or change the X-axis range, create a custom locator class that inherits from LogLocator:
import matplotlib.pyplot as plt from matplotlib.ticker import LogLocator class ScaledLogMinorLocator(LogLocator): def __init__(self, scale_factor, *args, **kwargs): super().__init__(*args, **kwargs) self.scale_factor = scale_factor # Store your 1.218 scaling factor def __call__(self): # Get the default minor ticks for a log axis, then scale them base_ticks = super().__call__() return base_ticks * self.scale_factor # Example usage x_vals = [10, 50, 100, 500, 1000] y_vals = [2, 4, 6, 8, 10] fig, ax = plt.subplots() ax.loglog(x_vals, y_vals) ax.set_xlabel("Lower X-axis (log10 scale)") ax.set_ylabel("Y-axis") # Add top axis with scaling top_ax = ax.secondary_xaxis("top", functions=(lambda x: x * 1.218, lambda x: x / 1.218)) top_ax.set_xlabel("Upper X-axis (1.218x lower axis, log10 scale)") # Assign the custom scaled locator to the top axis's minor ticks top_ax.xaxis.set_minor_locator(ScaledLogMinorLocator(1.218, base=10)) plt.tight_layout() plt.show()
How this works:
- The custom
ScaledLogMinorLocatoruses Matplotlib's built-inLogLocatorlogic to generate the base minor tick positions, then scales each by your 1.218 factor on the fly. - This means if you adjust the X-axis range (via zooming, panning, or code), the minor ticks on the top axis will automatically update to stay in sync with the scaled lower axis.
Notes:
- If you're using a different log base (e.g., natural log or log2), just adjust the
baseparameter inScaledLogMinorLocatorto match (e.g.,base=np.efor natural log). - Make sure your top axis is set to use a log scale too—since we're scaling log ticks, the top axis should mirror the lower axis's scale type.
内容的提问来源于stack exchange,提问作者Ben Pickering
相关产品推荐
相关产品推荐

